Skip to content

Instantly share code, notes, and snippets.

@futureperfect
Created March 16, 2025 20:43
Show Gist options
  • Save futureperfect/6822a2098cb5a1435513b60293456f47 to your computer and use it in GitHub Desktop.
Save futureperfect/6822a2098cb5a1435513b60293456f47 to your computer and use it in GitHub Desktop.
Silly async/await program to sort a list of numbers using workers and a shared resource
import asyncio
import bisect
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
async def sleep_and_sort(n, lock, result_list):
try:
logger.info(f"Sleeping for {n} seconds before doing work")
await asyncio.sleep(n)
logger.debug(f"Worker {n}: awake after {n} seconds")
async with lock:
logger.debug(f"Lock acquired, executing critical section")
bisect.insort(result_list, n)
logger.debug(f"Critical section finished, releasing lock")
except asyncio.CancelledError:
logger.error(f"Task {n}: cancelled")
async def main() -> None:
input_nums = [3, 1, 5, 4, 2, 7, 12, 2, 7, 8]
lock = asyncio.Lock()
result: list[int] = []
try:
_tasks = []
async with asyncio.TaskGroup() as tg:
_tasks + [tg.create_task(sleep_and_sort(n, lock, result)) for n in input_nums]
logger.info(f"Result: {result}")
except asyncio.CancelledError as e:
logger.error(f"Task cancelled and captured outside TG: {e}")
finally:
# do final resource cleanup here
logger.info("main: exiting")
if __name__ == "__main__":
with asyncio.Runner() as runner:
runner.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment