You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
asyncio: run newly scheduled callbacks eagerly before polling for I/O #160760
Currently, BaseEventLoop._run_once() runs only the callbacks that were ready when the iteration started. Callbacks scheduled by those callbacks wait for the next iteration, which first polls the selector (select()/epoll_wait()) with a zero timeout. Code that resolves futures, wakes tasks or chains call_soon() therefore pays for one I/O poll per hop, even when there is no I/O to process.
The good example is using asyncio.Queue: await q.put(item) pushes an item into the queue and wakes up the getter on the next event loop iteration only.
The same is true with network protocols: StreamReaderProtocol.data.received() feeds data to StreamReader and wakes await reader.read() after selector.select() call. Custom code that works with asyncio protocols (or loop.sock_recv()) explicitly suffers from the same problem.
If the code uses more moving parts, e.g. protocol->message-parser->user-code, each indirection level adds its own delayed call that increases latency.
I propose letting the loop keep running newly scheduled callbacks for a short, bounded time before it polls for I/O again (“eager processing”).
If after running scheduled callbacks (asyncio.Handler instances) there are new callbacks registered for the next loop iteration, they are executed immediately.
The implementation adds time- and count-based limits for eager callback execution for preventing possible infinite callbacks chain.
Has this already been discussed elsewhere?
I have already discussed this feature proposal on Discourse
The good example is using asyncio.Queue: await q.put(item) pushes an item into the queue and wakes up the getter on the next event loop iteration only.
If I clearly understand your description, does it cover and fix the following example, that breaks the FIFO's order of a queue ?
Activity
YvesDup commentedon Oct 27, 2026
If I clearly understand your description, does it cover and fix the following example, that breaks the FIFO's order of a queue ?
The output result is:
put: 1 put: 2 get: 1 put: 3 get: 3 get: 2pythongh-160760: asyncio: run newly scheduled callbacks eagerly befor…
pythongh-160760: asyncio: run newly scheduled callbacks eagerly befor…
pythongh-160760: asyncio: run newly scheduled callbacks eagerly befor…
pythongh-160760: asyncio: run newly scheduled callbacks eagerly befor…
pythongh-160760: asyncio: run newly scheduled callbacks eagerly befor…
pythongh-160760: asyncio: run newly scheduled callbacks eagerly befor…