Improving asyncio networking performance with aiofastnet and some thoughts on asyncio design

Hi all,

First, I wanted to drag attention my library aiofastnet .

If you’re using transport/protocol/streams from asyncio directly or indirectly, it will allow to significantly improve performance of your code especially for TLS connections. The idea is simple: use low level add_reader/add_writer and direct access to OpenSSL functions to re-implement transport/protocol networking and eliminate memory copying and python plumbing as much possible.

I hope some people will find it useful.

Second, while doing aiofastnet, I realized that the asyncio’s design around transport/protocol in general could be somewhat improved:

  1. Would be nice to have a clear attribute that says if loop is selector or proactor. Or have ABC like AbstractSelectorEventLoop or AbstractProactorEventLoop and derive actual loop from it.
  2. For AbstractProactorEventLoop specifically, there could be methods like sock_recv_impl, sock_recvinto_impl, etc that should NOT be async, should NOT return a Future, but instead just receive a simple callback and call it immediately when operation is complete. Do not post-pone it with call_soon or anything like that. This will close performance gap between selector and proactor implementations.
  3. Make transport/protocol implementation re-usable and replaceable. Right now, all 3rdparty loops have to re-implement it. asyncio, uvloop, winloop, have similar code for SelectorTransport and SSLTransport/SSLProtocol, and 99% of it is loop independent. There is no well-defined way to set transport/protocol implementation for the loop, except for monkey patching. Maybe something like asyncio.set_transport_protocol_policy or implementation is possible?

Apologies if these have been already discussed somewhere. I’m eager to hear your thought. Thank you in advance.

1 Like

Looks interesting. The benchmarks are nice. It’s worth pointing out it can be combined with uvloop.

Are there any libraries people are already using, that call the asyncio loop methods under the hood, that aiofastnet replaces? aiohttp?

1 Like

Thank you,

Yes, aiofastnet can be combined with any loop. It works on top of the current loop by providing alternative implementation for transport/protocol related loop methods like:

  • create_connection
  • create_server

Almost any asyncio library or application, which has to do something with networking use these methods directly or indirectly. Think of

  • uvicorn and starlette/fastapi through uvicorn,
  • All kind of db connectivity like asyncpg, aiomysql, aiopg, redis clients
  • HTTP libraries: aiohttp httpx async backend, websockets
  • RPC like grpclibs
  • anyio networking when used with asyncio
1 Like