Skip to content

Instantly share code, notes, and snippets.

@bourdeau
Last active May 23, 2024 17:40
Show Gist options
  • Select an option

  • Save bourdeau/8a29e36f5e25d101b6b200849436cad9 to your computer and use it in GitHub Desktop.

Select an option

Save bourdeau/8a29e36f5e25d101b6b200849436cad9 to your computer and use it in GitHub Desktop.
import asyncio
from random import randint
import aiofiles
import request
import aiohttp
async def async_http_request():
"""
I'm using aiohttp lib to make the http request and it's
fully async <3
"""
async with aiohttp.ClientSession() as session:
async with session.get("http://google.com") as r:
return await r.json()
async def blocking_http_request():
"""
This request is IO blocking and has no point being async.
It must be run in a executor.
Note: remember geocoding lib? You know what to do now ;)
"""
r = request.get("http://google.com")
return r.text
async def cpu_bound():
"""
I'm cpu bound. The time it will take to run will impact
all other coroutines.
I MUST be run in asyncio.run_in_executor() and has no point beeing async
"""
return [x*x for x in range(100000) ]
def sum(a, b):
"""
I'm not awaitable but I'm not IO blocking or CPU Bound.
I'm okay.
"""
return a + b
async def sync_open_file():
"""
This func open a file. It's pointless to make it async
as open is not awaitable and is IO blocking.
"""
with open("myfile.txt", "x") as f:
f.write("I just fucked up the event loop")
async def async_open_file():
"""
aiofiles is a lib which allow handling async file operation.
In reality it open the file another thread using asyncio.run_in_executor()
"""
async with aiofiles.open("myfile.txt", "x") as f:
await f.write("I'm friendly with other coroutine <3")
async def sync_sleep():
"""
sleep() is not awaitable as it is not
an async func. As sleep is basicaly a for loop
it will lock the event loop.
"""
sec = randint(1, 10)
print(f"Waiting: {sec}")
sleep(sec)
print(f"Finished {sec}")
async def async_sleep():
"""
This will run fully async <3
"""
sec = randint(1, 10)
print(f"Waiting: {sec}")
await asyncio.sleep(sec)
print(f"Finished {sec}")
async def main():
# Will just run smoothly. The shorter secs will finish first
await asyncio.gather(*(async_sleep() for i in range(10)))
# All blocking each others.
await asyncio.gather(*(sync_sleep() for i in range(10)))
# async coroutines will be blocked by sync_open_file
await asyncio.gather(async_sleep(), async_open_file(), sync_open_file())
# Not awaitable but will not mess with the event loop
sum()
# cpu_bound will lock the loop
await asyncio.gather(async_sleep(), cpu_bound())
# async_sleep will be blocked by blocking_http_request
await asyncio.gather(async_sleep(), blocking_http_request())
# Much better
await asyncio.gather(async_sleep(), asyncio.run_in_executor(blocking_http_request()))
# We make just a great coroutine couple <3
await asyncio.gather(async_sleep(), async_http_request())
# I hope it helps, but now I'm gonna grab a beer.
#
# If you want to understand asyncio read: https://www.npopov.com/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html
# It will save you many years of your life no matter the language you are programing with.
# And also: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
if __name__ == "__main__":
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment