Skip to content

symfonic.kernel.policies

policies

The G9 vocabulary every adapter attaches through (BP-1).

Separated from the adapters themselves so that the projections and the callback fan-out — which have genuinely different lifecycles — can each live in their own module without either importing the other. A shared row table and a shared lookup are not two responsibilities; they are the one thing both halves must agree on.

closing async

closing(source: AsyncIterator[_EventT]) -> None

Close a source the caller stops reading, deterministically.

An abandoned async generator is otherwise closed whenever the garbage collector gets to it — which means the run's teardown, the finalizers it holds, and the tasks it owns all run at an unpredictable later moment, in an unpredictable task. A projection that walks away closes what it walked away from.

Source code in src/symfonic/kernel/policies.py
async def closing(source: AsyncIterator[_EventT]) -> None:
    """Close a source the caller stops reading, deterministically.

    An abandoned async generator is otherwise closed whenever the garbage
    collector gets to it — which means the run's teardown, the finalizers it
    holds, and the tasks it owns all run at an unpredictable later moment, in
    an unpredictable task. A projection that walks away closes what it walked
    away from.
    """
    aclose = getattr(source, "aclose", None)
    if aclose is not None:
        await aclose()

declared

declared(plan: InvocationPlan, name: str) -> EventAdapter

Resolve an adapter's compiled row, or refuse to attach it at all.

Source code in src/symfonic/kernel/policies.py
def declared(plan: InvocationPlan, name: str) -> EventAdapter:
    """Resolve an adapter's compiled row, or refuse to attach it at all."""
    for policy in plan.event_program.adapters:
        if policy.name == name:
            return policy
    raise ContractViolationError(
        f"event adapter {name!r} has no compiled G9 declaration and cannot "
        "attach at run time (BP-1)."
    )