Explaining Async Programming With Pizza
Asynchronous programming. It means so many things to so many people.
When first learning async programming, it’s easy to confuse a language’s feature that allows async programming (async/await, callbacks) with async programming.
Today I’m going to introduce and explain asynchronous programming without diving into language specific code. If you know how a pizza shop works, you’ll be able to understand why async programming is so beneficial to web apps.
Bob’s Pizza Shop
Bob owns a pizza shop. He loves making pizzas and he has a system for making sure every pizza is great.
- Bob spends 10 minutes making a pizza
- Gives the pizza to the delivery guy, Joe.
- Waits for 30 minutes for Joe to deliver the pizza.
- When Joe gets back, he starts on the next pizza.
You might arguing that waiting 30 minutes for Joe to deliver the pizza is a waste of time, but that’s the way Bob prefers to run his pizza shop. If anything goes wrong with Joe’s delivery, he’s always free to handle the pizza crisis.
In Bob’s system, a customer gets a pizza every 40 minutes. Not the fastest in the business, but Bob wouldn’t do it any other way.
Amber’s Pizza Shop
Amber owns a pizza shop on the other side of town.
She grew up ordering from Bob’s Pizza Shop. She loved the pizza, but Bob could never make enough to keep up with demand. She has a quite a different system for making pizza.
- Amber spends about 10 minutes making a pizza.
- Gives the pizza to one of her delivery guys.
- Then proceeds to start making the next pizza.
Now instead of waiting 30 minutes, Amber gets right to work making the next pizza. If something goes wrong with a delivery, she trusts her delivery guys to let her know.
Pizza Shop Comparison
In both shops, making the pizza takes the same length of time. The difference is what Bob and Amber choose to do after the pizza is made? Bob waits while Amber continues making pizzas.
As you can see in this excel chart, Bob’s choice to wait causes him to only be able to make and delivery 2 pizzas in the same time it takes Amber’s shop to make and deliver 5 pizzas.
I think anyone looking at these two systems would immediately say Amber’s is better.
Introducing Some Programming Terminology
It’s easy for us to see that Bob is wasting his time waiting 30 minutes for the delivery to complete. He’s literally doing nothing.
Lets rephrase how Bob and Amber approach the delivery phase of the pizza cycle with some programming terminology.
We can say that after Bob makes his pizza, he blocks (ie, waits) until the delivery is complete. His blocking prevents him from being useful until the delivery guy returns.
We can also say that after Amber makes her pizza, she doesn’t block. She proceeds onto the next pizza. More programmatically, her interaction with her delivery guy is non-blocking.
This blocking v. non-blocking is the distinction that makes async programming so performant. In Amber’s case, her non-blockingness allows her output 2.5 times as much pizza as Bob does. (given enough delivery drivers)
Whenever there is some task where waiting is required, there’s always a choice on whether to block on that task, therefore wasting time, or not to block on that task and continue on.
Which brings us back to programming. In every app, much like the pizza shop, there’s a mix of short tasks where something needs to be done and long tasks where the app could just wait.
This small method does two things.
- Uses a repository to query from the database.
- Returns count or fewer number of questions.
Operation number #2 is fast. Everything happens in memory and it’s just creating a new list. In comparison, operation #1 takes a super long time. It has to make a network call to query the database. Network calls take forever in comparison to in memory programming (for most cases).
There’s two ways we can approach the database call. We can make that call in a blocking manner, or a non-blocking manner.
If we block on that network call, the thread that is making that call is sitting around doing nothing. Much like Bob was when he was waiting for his pizza delivery.
If we choose not to block on that network call, the thread is now free to go perform other programming tasks that need to be done.
Programming asynchronously, gives your applications the ability not to waste time waiting for something to happen. Which it turns leads to higher performance. Which everyone wants higher performance!
A Lot Left Unsaid
Obviously there are a lot of question left unanswered in this simple explanation. One of the biggest questions is, what happens to local state that is needed whenever a task resumes? That’s ultimately a question for another day, which is okay!
Having a solid understanding of the basic principles will only help you in your programming.
For me personally, I didn’t really understand async programming until a year and a half ago. And it took me another six months to really prioritize programming asynchronously whenever I had the ability to.
I was on a team and some of the developers used async and others didn’t, I didn’t think that was a big deal. Given what I know now, I would definitely push for everyone to be programming asynchronously. It would only help the performance of our application.
Async programming has the ability to unlock a higher level of performance in your applications! Modern programming languages make is easy (easier??) to programming in an async style. If your current language supports it I would definitely take the time to learn and utilize it.