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
I'd like to make sniffio.current_async_library() return "a name describing the type of the nearest enclosing async event loop".
This means:
If you run it from an async task, it returns the kind of trap you need to yield (same as today). If there is something clever going on such that you can yield multiple libraries' traps, the value could be any of them (so sniffio doesn't specify whether a trio_asyncio.allow_asyncio function would see "trio" or "asyncio").
If you run it from a non-task context on behalf of a particular loop (Trio abort_fn or instrumentation call or run_sync_soon function, asyncio call_soon/call_later/add_reader/add_writer callback), it returns that loop. This is an indication that you could spawn a new task on that loop, such as by using trio.lowlevel.spawn_system_task or asyncio.create_task. (That loop is not necessarily the only loop you could spawn a task on, because of guest mode and trio-asyncio.) It suggests that iterating an async generator here would cause the generator to be finalized in that context, but can't guarantee that (e.g. trio-asyncio doesn't implement mode-sensitive async generator finalization).
If there are multiple "layers" of async loop (due to synchronous foo.run() from a bar task or guest mode or trio-asyncio) you get the innermost one.
A thread spawned by an async loop is not considered part of that async loop.
I think this would fix #35, and would be an easier way than #27 to achieve similar semantics to #27.
Proposed mechanism of action:
If you are implementing a regular event loop, set sniffio.thread_local.name to your loop name at the start of run() and reset it to its previous value when run() exits (including via exception).
If you are implementing a guest-mode event loop, set sniffio.thread_local.name to your loop name at the start of a guest tick and reset it to its previous value when the guest tick finishes and you return to the host loop.
If you are implementing one event loop using async tasks in another event loop (I think trio-asyncio is the only example of this), set sniffio.thread_local.name to your loop name before entering a coroutine you're hosting and reset it to its previous value after that tick.
If the thread-local is None, then sniffio will sniff for asyncio via asyncio.get_running_loop() (rather than today's current_task()).
This also has some performance advantages:
current_async_library is quite fast; check a single thread-local attribute, and if it's not set then call a simple function implemented in C (asyncio.get_running_loop).
Simple cases (with just one library per thread) only set the thread-local once per run, not once per task step.
All complex cases I'm aware of still work.
Thoughts?
The text was updated successfully, but these errors were encountered:
I'd like to make
sniffio.current_async_library()
return "a name describing the type of the nearest enclosing async event loop".This means:
trio_asyncio.allow_asyncio
function would see"trio"
or"asyncio"
).trio.lowlevel.spawn_system_task
orasyncio.create_task
. (That loop is not necessarily the only loop you could spawn a task on, because of guest mode and trio-asyncio.) It suggests that iterating an async generator here would cause the generator to be finalized in that context, but can't guarantee that (e.g. trio-asyncio doesn't implement mode-sensitive async generator finalization).foo.run()
from abar
task or guest mode or trio-asyncio) you get the innermost one.A thread spawned by an async loop is not considered part of that async loop.
I think this would fix #35, and would be an easier way than #27 to achieve similar semantics to #27.
Proposed mechanism of action:
sniffio.thread_local.name
to your loop name at the start of run() and reset it to its previous value when run() exits (including via exception).sniffio.thread_local.name
to your loop name at the start of a guest tick and reset it to its previous value when the guest tick finishes and you return to the host loop.sniffio.thread_local.name
to your loop name before entering a coroutine you're hosting and reset it to its previous value after that tick.asyncio.get_running_loop()
(rather than today'scurrent_task()
).This also has some performance advantages:
current_async_library
is quite fast; check a single thread-local attribute, and if it's not set then call a simple function implemented in C (asyncio.get_running_loop
).Thoughts?
The text was updated successfully, but these errors were encountered: