Skip to content

gh-160760: asyncio: run newly scheduled callbacks eagerly before polling for I/O - #145149

Open
asvetlov wants to merge 1 commit into
python:mainfrom
asvetlov:eager-loop
Open

asvetlov wants to merge 1 commit into
python:mainfrom
asvetlov:eager-loop

Conversation

@asvetlov

@asvetlov asvetlov commented Feb 23, 2026 •

Copy link
Copy Markdown
Contributor

Run callbacks that are scheduled during an event loop iteration eagerly, within a small budget, instead of always waiting for the next I/O poll. This removes one select()/epoll_wait() call per hop in code that resolves futures or wakes tasks in chains.

  • New asyncio.EventLoopSettings(eager_max_time, eager_max_callbacks) and loop.get_settings() / loop.set_settings(). The defaults are 100 µs and 100 callbacks; eager_max_time=0 turns eager processing off.
  • Eager processing ends early on asyncio.sleep(0), which still guarantees an I/O poll, and on loop.stop(), which keeps its documented "current batch only" behaviour.
  • Callbacks still run in first-in, first-out order. Only the number of I/O polls changes.

Benchmarks (release build, script): a call_soon() chain is 38% faster, Queue ping-pong 25% faster, and a task awaiting a child task 33% faster. Servers with many connections are unchanged. While a long run of callbacks keeps going, timers and I/O can be delayed by up to about 100–200 µs.

A few tests that assumed "one task hop = one I/O poll" were adjusted.

@github-actions

This comment was marked as outdated.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label May 7, 2026
@asvetlov asvetlov changed the title Implement eager loop runner #160760: Implement eager loop runner Oct 27, 2026
@asvetlov asvetlov added topic-asyncio and removed stale Stale PR or inactive for long period of time. labels Oct 27, 2026
@asvetlov asvetlov changed the title #160760: Implement eager loop runner gh-160760: asyncio: run newly scheduled callbacks eagerly before polling for I/O Oct 27, 2026
@bedevere-app bedevere-app Bot added the type-feature A feature request or enhancement label Oct 27, 2026
@read-the-docs-community

read-the-docs-community Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

@asvetlov
asvetlov force-pushed the eager-loop branch 6 times, most recently from 2950322 to 917f47b Compare October 28, 2026 15:33
@asvetlov
asvetlov marked this pull request as ready for review October 29, 2026 10:42
@asvetlov
asvetlov requested a review from 1st1 as a code owner October 29, 2026 10:42
Comment thread Lib/asyncio/base_events.py Resolved
Comment thread Lib/asyncio/base_events.py Resolved
Comment thread Lib/asyncio/events.py Resolved
Comment thread Lib/asyncio/events.py Resolved
Comment thread Lib/asyncio/constants.py Resolved
@YvesDup

YvesDup commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Sorry, but I don't see in any tests, assertion on the _eager_state attribute used as a counter even it is a private attribute ? Maybe I missed something.

@asvetlov

asvetlov commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Right, no test asserts the value of _eager_state directly. That's on purpose: it's a private detail, so the tests check what it controls: which callbacks run in which iteration, what is left in _ready, and how many times the selector is polled. To make sure this covers the counter, I tried storing no count, a count one too high and a count one too low; each change makes test_run_until_complete_after_eager_limit fail, and most of them also make some of the test_run_forever_stop_* tests fail.

@YvesDup

YvesDup commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

That sounds good to me.

…e polling for I/O

Run callbacks that are scheduled during an event loop iteration eagerly,
within the limits of the new asyncio.EventLoopSettings, instead of always
waiting for the next I/O poll.  asyncio.sleep(0) and loop.stop() end
eager processing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants