Async Programming: Do Not Waste Time

Search for a command to run...

No comments yet. Be the first to comment.
This is neither some notes nor advice based on my experience of using Temporal as data orchestrator for my ETL pipeline. Initially I felt it just the same as other orchestrators like Airflow, Prefect, or Dags or what so ever, however I learned it in ...

I just watched Zach video (the famous data engineer guy that has worked for Airbnb and Facebook) and want to build something with it. I am lacked with data engineer experience so I decided to build something while learning. Previously, I just felt th...

Meet again in the episode of I re-learn something that I don’t applied in my daily work task. Yeah, just want to learn it again and I hope this time I get the most of the understanding. I will push myself for this three months to re-learn DSA, before...

Personally, Kaggle is sufficient enough for someone for data science starter, or even to delve deeper in data science field. This article was written after having a conversation with a Kaggle Master, listening to some Kaggle Grandmaster Podcast, and ...

In a simple words, async’s philosophy is - while waiting, do something!
Async, or asynchronous is not as an asing things in programming. However, due to no real world use case for utilization of the concept, I tend to ignore it in my codes. Then it has became my concerns in my current working project as it required me to build a vast and robust pipeline that is operated efficiently and relatively faster.
Time is money
Speed
Optimization
Use it whenever you have a function that took so much time, yet you want other function to run int the background or while waiting the slow guy to complete.
Use it when you want to increase the efficiency of the code, increase the potential and speed of the operation by not blocking other function(s).
Below is the approaches to complete any process or operation, or any task in life. To understand this, imagine a situation when a man need to cook a burger in a restaurant. The man need to completed 10 set of burgers by following the common cooking process.
Man cook a patty with no timer.
Man waiting until the patty cooks and cannot do the next step until the patty is cooked. (blocking)
Once cooked, man slice the bread.
Man then frying the fries with no timer features. Man waiting until fries is completely cooked. (blocking)
Man put lettuce and mayo on the bread and stack up with the patty.
Man put fries as side dish.
Man do step 1 to 4, until it completed 10 burgers.
Man tired.
Took so so much time. :(
Man cook a patty.
While waiting patty to cook, man slice a bread.
Man go flip the patty and set a timer for five minutes.
While waiting patty cook, man fry fries in a fryer with timer for 3 minutes.
Man put lettuce on the bread.
While waiting the patty cook, fry timer ended. Man take the french fries and put in the plate.
Patty cooked, man put patty on the stacked bread with lettuce.
Fast and efficient.
Man-A cook a patty, Man-B slice bread, Man-C frying fries, Man-D arrange the lettuce.
While patty cook, Man-B take lettuce on bread, Man-C put the fries on the plate.
Patty cook, Man B took patty and stack on bread.
Complete.
Faster, but more complex to control more men.
Do async function for function that potentially taking too much time.
Wrap the expression(s) in a function. Atomize it.
Prefix with async and await the async-ing function.
In Python, we will handle the async function with asyncio Package and it will do all the magics behind it.
Task is fancy terms for the function you want to execute. Task is optional. You can explicitly create it with with asyncio.create_task() or, directly run it with asyncio.run() or asyncio.gather() + asyncio.run() for multiple async function.
asyncio.create_task() — create task immediately, can run later with await if you want, independent task, cancellable
asyncio.gather() — gather all coroutine function together, don’t want run the function later, non cancellable, return list
async function():
asyncio.sleep(10) # just to simulate a time consuming function
return "a"
async function()_1:
asyncio.sleep(10)
return "b"
async function()_2:
asyncio.sleep(10)
return "c"
async function()_3:
asyncio.sleep(10)
return "b"
async def main():
# singlefunction
asyncio.run(function())
# multiple async function
asynction.gather(function_1(), function_2(), function_3())
# run the corouting function
asyncio.run(main())
import asyncio
async def do_things():
print("Currently doing things...")
asyncio.sleep(100) # fake a function that took so much time!
return "yes"
async def process_output(out):
if out == "yes":
return "completed"
def check_something():
out = await do_things()
process = await process_output(out) # need to await coz do_things took time to complete
return process
asyncio.run(check_somoething)
# await check_something() # notebook
Output:
"yes"
There is sync function that will blocked the operation (legacy, or unsupported)
asyncio.to_thread() | asyncio.loop.run_in_executor()
function():return "a" # sync, legacy or unsupported for async
async function()_1:return "b"
async function()_2:return "c"
async function()_3:return "b"
async def main():
# singlefunction
asyncio.run(asyncio.to_thread(function())) # or loop.run_in_executor()
# multiple async function
asynction.gather(function_1(), function_2(), function_3())
# run the corouting function
asyncio.run(main())
| Issue | Potential Solution |
function or expression is not awaited | check whether function has async or notwrap the expression as async function so that it can be awaited, although it does not consume time to return output |
object coroutine is not iterable (list), hashable (dict) | check whether the function call which output is passed to variable is awaited or not |
async def load_something(): return "complete" output = load_something() ❌ output = await load_something() ✅ asyncio.run(load_somoething) ✅ |
Legacy sync function.
Unsupported async feature in package.
Some function easily handled as sync.
For time consuming function, make it async. Use async in front of def.
Calling async function require you to use await. Hence include it if it is called.
Start with asyncio.run() for easy execution of async function. Then can try asyncio.gather([list of async function]) + asyncio.run() for multiple async functions.
Once comfortable, implement intermediate async feature, such async time base, prioritization base, and queue.
I hope this will help the beginners or any level of programmer to understand the async concept. If you have any commenta, please leave the comment below. I appreciate it. Thank you.