Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add eager task creation API to asyncio #97696

Closed
@jbower-fb

Description

@jbower-fb

Feature or enhancement

We propose adding “eager” coroutine execution support toasyncio.TaskGroup via a new methodenqueue() [1].

TaskGroup.enqueue() would have the same signature asTaskGroup.create_task() but eagerly perform the first step of the passedcoroutine’s execution immediately. If thecoroutine completes without yielding, the result ofenqueue() would be an object which behaves like a completedasyncio.Task. Otherwise,enqueue() behaves the same asTaskGroup.create_task(), returning a pendingasyncio.Task.

The reason for a new method, rather than changing the implementation ofTaskGroup.create_task() is this new method introduces a small semantic difference. For example in:

async def coro(): ...async with TaskGroup() as tg:  tg.enqueue(coro())  raise Exception

The exception will cancel everthing scheduled intg, but if some or all ofcoro() completes eagerly any side-effects of this will be observable in further execution. Iftg.create_task() is used instead no part ofcoro() will be executed.

Pitch

At Instagram we’ve observed ~70% of coroutine instances passed toasyncio.gather() can run fully synchronously i.e. without performing any I/O which would suspend execution. This typically happens when there is a local cache which can elide actual I/O. We exploit this inCinder with a modifiedasyncio.gather() that eagerly executescoroutine args and skips scheduling aasyncio.Task object to an event loop if no yield occurs. Overall this optimization saved ~4% CPU on our Django webservers.

In a prototype implementation of this proposed feature [2] the overhead when schedulingTaskGroups with all fully-synchronous coroutines was decreased by ~8x. When scheduling a mixture of synchronous and asynchronouscoroutines, performance is improved by ~1.4x, and when nocoroutines can complete synchronously there is still a small improvement.

We anticipate code relying on any semantics which change betweenTaskGroup.create_task() andTaskGroup.enqueue() will be rare. So, as the TaskGroup interface is new in 3.11, we hopeenqueue() and its performance benefits can be promoted as the preferred method for scheduling coroutines in 3.12+.

Previous discussion

This new API was discussed informally at PyCon 2022, with at least some of this being between@gvanrossum,@DinoV,@markshannon, and /or@jbower-fb.

[1] The name "enqueue" came out of a discussion between@gvanrossum and@DinoV.

[2]Prototype implementation (some features missing, e.g. specifying Context), andbenchmark.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Done

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp