Async Techniques and Examples in Python Transcripts
Chapter: async and await with asyncio
Lecture: Demo: The producer-consumer app
0:00 Let's begin our exploration of asyncio
0:02 by looking at this common pattern
0:03 called a producer, consumer pattern.
0:06 The idea is, there's some part of the system
0:08 that typically runs independently
0:10 asynchronously, that generates items.
0:14 Maybe it receives a request to fulfill a job
0:17 charge to this credit card, send these emails
0:20 import this data file, things like that.
0:22 There's another part of the system
0:24 that is also running asynchronously
0:26 that looks for work to be done, and as the consumer
0:30 it's going to pick up these jobs that are created
0:31 by the producer, and start working on them.
0:34 I have an extremely simple version of that here.
0:38 It doesn't really do anything useful.
0:40 So, we have generate data, and we have process data.
0:43 And we're just using this list to share
0:44 to exchange data between these two.
0:47 So, let's look at generate data.
0:49 It's going to go, and just create the square
0:51 of whatever number we give it
0:54 and it's going to store in our list, a tuple.
0:56 So that's one thing going in the list that is a tuple
0:58 the item that was generated, and the time at which
1:02 that generation happened.
1:03 And then it prints out in yellow.
1:04 We're using this cool library, called Colorama
1:06 to do different colored output.
1:08 And color, in threading concurrences
1:10 is super helpful to understand what part is happening where
1:13 and what order it's all happening in.
1:16 We're also flushing everything
1:17 to make sure there's no delay in the buffer
1:20 when we print stuff.
1:21 As soon as we say print, you see it.
1:22 So, to simulate it taking some time to generate some data
1:26 or do the producer side, we call time.sleep()
1:29 for between 0.5 and 1.5 seconds.
1:32 On the process data side we're going to look for some data
1:36 if it's not there, this structure doesn't really
1:37 have a concept of get it, and wait
1:40 we'll talk more about that later.
1:42 But once an item comes in, we just grab it.
1:44 In cyan we say we found it, and we also print out
1:47 and we determine how long, from when it was created
1:51 till we were able to get to it, and process it.
1:53 Because the lower that number, the more concurrency
1:56 the better we have.
1:57 A soon as something is deposited for us to use, and pick up
2:00 we should immediately get to it. But this code is synchronous.
2:04 We do all the generation, then all the processing.
2:07 So the first item is not going to be processed
2:09 until all the generation is done, in this 20, and 20.
2:12 Let's just run it and see what this means.
2:14 The app is running, you can see we're generating in yellow.
2:18 It's kind of a subdued color in the pycharm terminal
2:20 but yellowish it's going to come out
2:21 and cyan for the consumer. We're waiting for all 20.
2:32 There we are. Now we're starting to process them.
2:35 Notice, we were not able to get to the first one
2:36 until 20 seconds after it was created.
2:39 Now, the consumption of these is faster than the production
2:42 so we were able to catch up somewhat
2:44 and we got it down to 10 seconds, 10.48 seconds
2:48 for the best case scenario.
2:50 You can see these numbers that we picked up out of there
2:53 were the ones generated previously.
2:55 In the overall time it took to run that
2:57 was 30, 31-ish seconds.
3:00 None of this is great, and we can actually
3:02 dramatically improve this with asyncio.
3:05 Not a little bit, a whole lot.