tractor/ai/prompt-io/opencode/20260828T014247Z_d06ee34b_p...

2.0 KiB
Raw Blame History

Prompt

Get PR #490 primed and landed. Continue after rebasing, but keep the review and fix pass focused.

Response

The mutable {} default is safe because msgspec.Struct creates a fresh dictionary per instance. A separate concurrency defect remains: two tasks can call receive() through one BroadcastReceiver, and the second call overwrites the only _wait_scope. Closing that receiver can then leave the first task blocked indefinitely.

git diff -- tractor/trionics/_broadcast.py tests/test_task_broadcasting.py

Added a per-receiver in-progress guard that raises trio.BusyResourceError for an overlapping receive. Added a regression test that blocks the first receive, verifies the second call is rejected, and releases the source to prove the first call still works. The complete broadcast test file passes: 28 tests in 4.57 seconds.

Follow-up prompt

Clarify that the guard is per receiver, preserves lossless consumer semantics, and document the contract on the public method, type, and surrounding guide.

Follow-up response

git diff -- tractor/trionics/_broadcast.py docs/guide/streaming.rst

Documented that each BroadcastReceiver owns one logical cursor, each concurrent consumer needs its own subscribed receiver, overlapping calls on one handle raise BusyResourceError, and strict lag handling never skips values silently.

Second follow-up prompt

Explain that the polling loop waits until the background receive is blocked before making the concurrent call, and include the first consumer tasks runtime information in the busy exception.

Second follow-up response

Replaced the boolean guard with the active trio.lowlevel.Task, added its name and representation to BusyResourceError, named the fixture task for a deterministic assertion, and documented the checkpoint-loop interleaving directly above the poll.