I first came across sync (synchronous) and async (asynchronous) programming while I was studying for my Cisco DevNet certifications. It was hard to understand at the time why I needed to know about these two programming terms, but after creating some more complex scripts and apps, I started understanding why each concept was important. In this post, I hope that I can explain these terms, and more importantly, why you would want to apply them in your own apps and scripts.
What’s the difference?
You can think of synchronous programming as the “normal” programming method you’re used to. You execute a task and wait for a response to be returned. While waiting for the task to finish, you may see a loading indicator, such as a spinning circle. If there’s a series of tasks that need synchronously executed, each task will be executed sequentially with every task waiting for the previous task to finish before proceeding. To the user, this will just result in a longer-lasting spinning circle (not cool).
You may ask, “What’s wrong with this sort of programming? I don’t mind waiting for a response… it gives me a reason to go grab a coffee.” While that may be true, we would be in trouble if all of our apps executed tasks like this. Think about the checkout process at a large ecomm site like Amazon or Ebay. When you click the ‘Checkout’ button, there are many tasks being executed in the background, such as executing the payment, emailing your order receipt, updating inventory, adding your order to its warehouse shipping queue, and many others. Now, I don’t want to lead you on that all these processes lead back to sync vs. async programming because there are different app architectures that allow these processes to happen simultaneously and independently (i.e. microservices). The point I’m trying to get across is that these processes all occur in the background when you click the checkout button and the only validation/response you receive back from the ecomm site is “order placed!”.
Asynchronous can be a tricky and confusing topic. Let’s try to knock out some of the confusion before we dive into what it is. Async should not be confused with multi-threading. Multi-threading is managed by the operating system and allows pieces of application code to be sliced up and executed among multiple threads on a processor. Without multi-threading, a processor core simply executes one command at a time. In today’s world, it’s common to find computer processors with multiple cores and each core having multiple threads, so you get the benefit of having multiple cores with multiple threads in every processor 👍. Async programming allows for multiple tasks to be scheduled and ran at different times (vs. sequentially with sync programming). Async tasks can actually be ran on a single thread, so it’s not the same as multi-threading. I wanted to clear the air on that topic, as some may assume that async allows you to execute multiple tasks at the same time by running each task in a separate thread, which is not correct. That sort of execution is commonly referred to as threading in software programming, which is different than async.
Some common tasks that you would consider for async execution would be batch processing, long-running tasks, and independent tasks. Batch processing allows your program to split up tasks with large amounts of data, and run them in parallel to avoid blocking CPU resources for long periods of time. Long-running tasks are pretty straightforward, but let’s revisit the ecomm checkout example we looked at in the sync section. If we had to wait for every task we highlighted in that section (executing payment, emailing receipt, etc.) to run and complete sequentially, then we would be waiting a little longer than a couple seconds to checkout. The last use case, independent tasks, can be defined as any task that can be ran by itself and does not have any dependencies on other tasks’ results. This may seem straightforward, but try considering a small task like sending a confirmation email. Does this task rely on any other task results? What about the payment execution? Does it wait for the payment to be confirmed before sending the email, or do you send the email in parallel with the payment process? These decisions need to be made before you think about whether each task is sync or async. Order of operations and mapping out your task dependencies are crucial when figuring out when to use async programming.
Now we didn’t go into the technical details of async programming, as there are many software engineering blogs out there that can better highlight the technical aspects. However, for network engineers looking to implement async functionality into their network automation scripts, the asyncio Python library is a great place to start. Asyncio is included in the standard Python library and allows you to build async functionality into your code. I highly recommend checking out the documentation if you’d like to learn more.
So async is the way to go?
Not necessarily. Just because async is the “faster” method to execute tasks, it doesn’t necessarily make it the best choice. As with everything in technology, it depends. It depends on the functionality of the function or app. It depends on how you want your user to experience your app. The biggest consideration is whether the results from one task are required for the execution of a subsequent task. At the most basic form, does Task B rely on the results of Task A, or can Task A and B be executed independently of one another (no dependency on one another)? If you answered with the latter, there’s a good chance that your tasks can be ran asynchronously. There are plenty of other considerations as well… At the end of the day, you need to choose based on your specific requirements, including order of operations.
This is a shorter post, but I wanted to write this in hopes of connecting with someone else’s curiosity for sync vs. async functionality. I know when I first started looking at these concepts, I wanted to find the simplest and most concise explanations. Hopefully, I was able to help you understand the importance of each concept. If you have any questions or feedback, please feel free to hit me up on Twitter (@devnetdan). Thanks for reading!