Last active
May 23, 2024 17:40
-
-
Save bourdeau/8a29e36f5e25d101b6b200849436cad9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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