Co-authored and implemented PEP 362: inspect.signature API. • Authored and implemented PEP 492: async/await syntax. • Co-maintainer of asyncio with Guido and Victor Stinner. • Created uvloop.
• Callbacks and Deferred. • Stackless Python & greenlets. • Coroutines using generators and yield. • Coroutines using generators and yield from. • And now we have async/await.
• New builtin type for coroutines. • New concepts: async for and async with. • Generic, framework agnostic design. • Fast: only ~2x slower than a function call. Why async/await is the answer
event loop. • Interfaces for Protocols and Transports. • Factories for servers and connections; streams. • Futures and Tasks: callbacks + coroutines, timeouts, cancellation, etc. • Subprocess, queues, synchronisation primitives.
the foundation of asyncio. • Factories for Tasks and Futures. • IO multiplexor. • Low level APIs for timed events, scheduling callbacks, subprocesses and signals. • And… you can replace it.
• Use loop.sock_* for easy porting synchronous code to asyncio. Better consider using Streams. • Use Streams for implementing protocols with async/await. • Use Protocols and Transports for performance.
pushes data to Protocols. • Protocols send data back using Transports. • Protocols can implement specialized read and write buffers. • Protocols can do flow-control. • Full control over how IO is performed.
format. • That means more efficient encoding of data -> less network traffic -> faster IO. • Binary means much faster parsing. Always prefer binary. • Not all Postgres types can be unambiguously parsed when transferred as text.
idea: let’s build an efficient driver for Postgres. Use its features to the max. • Supports all built-in Postgres types; composite and custom types. github.com/magicstack/asyncpg
So we use them extensively. • Each connection has an LRU cache of prepared statements. • We dynamically build and cache pipelines of data encoders and decoders for each statement. github.com/magicstack/asyncpg
in two classes: CoreProtocol and Protocol(CoreProtocol). • CoreProtocol class knows almost nothing about asyncio. • Protocol class is the bridge between the world of callbacks and async/await.
use Python bytes type and/or memoryviews. • Problem: the driver will spend a lot of time allocating and deallocating memory. The performance will suffer.
Use asyncio Protocols and Transports to create high performance protocols. • Use Cython for low level code. It’s amazing. • async/await should always be the preferred public API. • Once you have fast drivers, your application will work fast. Use async/await.
your code. Always. • Cython code can be profiled with valgrind; results visualized with KCachegrind. • Use `cython -a` option to generate HTML output for your Cython code.
• Prefer C data types; working with Python bytes is expensive. • Have efficient buffer to build requests and one buffer with ‘transport.write’. Or use multiple buffers and a single ‘transport.writelines’.
no control over how transport.write is called, use TCP_CORK option to buffer writes and send as few TCP packets as possible. • Use TCP_NODELAY to send data as soon as you call ‘transport.write’.