Advanced asyncio: Solving Real-world Production Problems

Lynn Root

ASYNC / Concurreny Best Practice Development

By building a simplified chaos monkey service, we will walk through how to create a good foundation for an asyncio-based service, including graceful shutdowns, proper exception handling, and testing asynchronous code. We’ll get into the hairier topics as well, covering topics like working with synchronous code, debugging and profiling, and working with threaded code. We’ll learn how to approach asynchronous and concurrent programming with Python’s asyncio library, take away some best practices, and learn what pitfalls to avoid.

Outline:
(40 minutes + 5 min Q&A, if unable to get 45 minutes, then 30 min slot with no time for Q&A)

1. Intro (2m)
- Speaker/company intro
- Setting the context/purpose of talk

2. Foundations (9m - trimmed to 6m for 30 min slot)
- Initial setup of an asyncio service (2m)
--- Required boilerplate code
--- Inspiration from official asyncio tutorial docs
- Making a service *actually* concurrent (5m)
--- non-blocking vs concurrent
--- when to be concurrent vs serial
--- using callbacks vs awaits vs scheduling tasks (create_task) vs asyncio.Events
--- Making synchronous code asyncio-friendly (2m)

3. Intermediate (9m - trimmed to 6m for 30 min slot)
- Graceful shutdowns (3m)
--- What a signal handler is, why it’s needed
--- What signals to listen to
--- Gotchas of cancelling tasks, asyncio.shield + shutdown behavior
- Exception handling (3m)
--- Difference between top-level exception handling and handling within other coroutines
--- Avoid mistakenly swallowing/missing raised exceptions
--- Making use of loop.set_exception_handler
- Making threaded code asyncio-“friendly” (3m)
--- Calling threaded code from coroutines (aka running within a ThreadPoolExecutor)
--- Calling coroutines from from threaded code (aka run_coroutine_threadsafe)

4. Advanced (19m - trimmed to 15m for 30 min slot)
- Testing asyncio code (7m)
--- Benefits of debug mode
--- How to mock coroutines
- Debugging an asyncio service (5m)
--- Reinforce debug mode
--- Using “tricks" like `asyncio.all_tasks` with logging, `loop.slow_callback_duration`, adding context/stack trace in default exception handler
- Profiling (7m)
--- Basic profiling (cProfile, strace) - not that different from sync code
--- Continuous profiling with 3rd party tools, i.e. github.com/what-studio/profiling
--- PyCharm’s asyncio & thread profiler
--- How to properly trace a workflow/request (e.g. for the purpose of distributed tracing) (to be cut if not enough time)

5. Wrap up/Review (1m)

Type: Talk (45 mins); Python level: Intermediate; Domain level: Intermediate

Lynn Root

Spotify

Lynn Root is a Staff Engineer at Spotify with historical issues of using her last name as her username, and the resident FOSS evangelist. She is also a global leader of PyLadies and former Vice Chair of the Python Software Foundation Board of Directors. When her hands are not on a keyboard, they are usually holding a bass guitar.