symfonic.kernel.contracts.run_callbacks¶
run_callbacks ¶
The lineage a loop callback keeps from the code that scheduled it.
loop.call_soon(cb, context=contextvars.Context()) inside a kernel run --
or from a task spawned with a stripped context -- runs cb in no task with
no lineage in context, so a task it creates and a run that task issues would
start as roots and launder what the scheduler was handed after a forget
(CORE-199). asyncio has no hook where a callback is scheduled, so the kernel
shadows the running loop's scheduling methods on the loop instance:
call_soon, call_soon_threadsafe, call_later and call_at. The
shadow resolves the scheduler's origin -- its lineage, as the task factory
resolves it, or a task the factory never saw, which the census resolves only
if the callback builds a task or issues a run -- and, if there is one, hands
it to the callback for exactly its call (run_spawn); the callback
still runs in the context it was given, so no other context variable reaches
it. A scheduler with no lineage hands nothing on, so an unrelated request's
callbacks -- a server's per-connection ones -- stay roots.
A callback bound to a future or task (a task's step, a future's
set_result) is passed through: a task resolves its own record, never the
callback's. A done-callback is scheduled by the code completing its future,
so it is handed that code's lineage.
Measured to carry on CPython 3.12's selector loop and uvloop 0.22.1: both take
the instance attribute, and user code and C tasks call it. A loop that refuses
it carries nothing, so the kernel refuses every run there, typed, before the
run starts (run_spawn): the shadows are installed all or none, the
methods already shadowed are restored, and the loop is remembered so a later
run refuses too. Not covered: a callback scheduled through a loop's internal
path (a transport's protocol callbacks), work on another thread, an explicit
executor or another process (run_spawn).
called_lineage ¶
track_callbacks ¶
Shadow all of loop's scheduling methods, or none; whether the loop carries.