tractor/tractor/trionics
Gud Boi 6429e6a515 Reject concurrent `BroadcastReceiver.receive()` calls
Two tasks could receive through one `BroadcastReceiver` and race its
single `_wait_scope`. A later call could replace the scope, leaving
the first blocked through `.aclose()`.

Track the active `trio.lowlevel.Task` per receiver and reject an
overlapping call with `trio.BusyResourceError`. Include the owner's
task name and repr in the error, then clear ownership in `finally`.

Define each receiver as one logical subscription cursor. Concurrent
consumers must use separate `.subscribe()` receivers so each retains
an independent cursor and lag policy. Strict mode reads every retained
value or raises `Lagged`; `raise_on_lag=False` explicitly permits
drops.

Cover the regression with a checkpoint loop synchronized on
`recv_ready`; explain the interleaving inline, assert the error names
the active consumer, then release the source and prove the original
receive remains usable.

Prompt-IO: ai/prompt-io/opencode/20260828T014247Z_d06ee34b_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
2026-08-27 22:11:55 -04:00
..
patches Add `tractor.trionics.patches` subpkg + first fix 2026-06-17 17:39:44 -04:00
__init__.py Wake broadcast peers on shared receive failures 2026-08-27 21:18:00 -04:00
_beg.py Mk temp collapser bp work outside runtime as well.. 2025-08-18 10:46:37 -04:00
_broadcast.py Reject concurrent `BroadcastReceiver.receive()` calls 2026-08-27 22:11:55 -04:00
_mngrs.py Clarify `maybe_open_context()` teardown notes 2026-08-11 11:38:43 -04:00
_subproc.py Clarify eg-wrap contract + tighten `stdout` typing 2026-06-24 19:09:45 -04:00
_taskc.py Match Trio's startup error exactly 2026-08-12 15:45:23 -04:00