Hi community!
In asyncio internals or the internals of other modules that implement features on top of it, there is a lot of loop.call_soon
. Does anyone know when call_soon
should be used for callbacks, and when callbacks should be called directly?
Example 1: asyncio.Server
accepts a connection:
BaseSelectorEventLoop._accept_connection
creates Task_accept_connection2
BaseSelectorEventLoop._accept_connection2
- creates Future
waiter
- creates
_SelectorSocketTransport
, passes in waiter - awaits
waiter
- creates Future
_SelectorSocketTransport.__init__
call_soon(protocol.connection_made)
call_soon(self._add_reader, ...)
self._loop.call_soon(futures._set_result_unless_cancelled, waiter, ...)
BaseSelectorEventLoop._accept_connection2
- was awaiting Future
waiter
, which is now complete
- was awaiting Future
Wouldn’t this do the same without the extra Task, Future, and call_soon
s?
Example 2: _SelectorSocketTransport
receives data from a TCP socket:
_SelectorSocketTransport._read_ready
calls_read_ready_cb
_SelectorSocketTransport._read_ready_cb
calls_read_ready__data_received
_SelectorSocketTransport._read_ready__data_received
callsprotocol.data_received
In this case it was elected not to use call_soon
even though, arguably, data_received
is a callback.