In `.open_channel_from()`, when the `trio`-side parent task exits, it
signals the running `asyncio`-side task with `TrioTaskExited`; this is
our internal exit signal to any still-running `asyncio` task. When the
`asyncio`-side raises the issued signal, previously
`translate_aio_errors()` let it escape despite
`suppress_graceful_exits=True`, (in `piker`'s case) turning an expected
(and cached via `.trionics.maybe_open_context`) channel teardown into
a (quote-feed) task-restart failure.
Now if that task raises the same signal, `translate_aio_errors()`
suppresses it when `suppress_graceful_exits=True`, while preserving any
original `trio`-side error. There are two cooperating fixes:
1. `translate_aio_errors()` returns early without raising that TTE. This
prevents normal channel teardown from propagating it back up to
the originating task.
2. The `asyncio` done callback `signal_trio_when_done()` now returns
early for that same TTE ack and prevents it from
recancelling the already-unwinding `trio-side` or raising the signal
again as an unhandled callback error.
Deats,
- record the issued `TrioTaskExited` instance in
`LinkedTaskChannel._aio_owner_exit` before signalling the
`asyncio`-side task, retaining the original `trio`-side error
as its cause when present.
- use exception identity (`is`), rather than type, to recognize
that issued signal; a separately raised TTE or another
`asyncio`-side cleanup error retains existing error handling.
- in `translate_aio_errors()`, require the `trio`-side parent
task to have exited before handling the acknowledged signal:
- raise any original `trio_err` first, without making its own
exit signal its cause and creating an exception-cause cycle;
- OW return early under `suppress_graceful_exits=True`;
- with suppression disabled, raise the exact issued TTE.
- in `signal_trio_when_done()`, retrieve the task exception but
skip parent-task recancellation and callback error relay when
it is that issued TTE and the `trio`-side has already exited.
- in `wait_on_coro_final_result()`, retain the issued TTE in
`chan._aio_err` for the reporting decision above, logging its
receipt as an exit acknowledgement rather than a task failure.
- retain the actual `maybe_signal_aio_task()` delivery report
for both acknowledgement logs; include the `trio`-side parent
task via `pformat_task()`, its original error/cancellation cause,
and runtime-level diagnostics for each reporting decision.
Update docs/reporting,
- document the signal writer, readers and teardown outcomes;
- retain the actual signalling report for both acknowledgements;
- use `pformat_task()` to identify the `trio.Task` in diagnostics;
- distinguish the parent's error from its issued TTE;
- log suppression, strict reporting and `trio`-side-error precedence;
- clarify graceful suppression for cached-channel teardown;
- keep the queue-shutdown TODO beside its existing handler.
Qualification using a separate, uncommitted regression module:
- original matrix 8 failed / 4 passed; candidate matrix 12 passed.
- selected bridge/formatter run: 41 passed / 18 deselected.
- earlier `piker` real-channel integration: 4 passed.
- human reset traces acknowledge owner exit and preserve a quote
`TimeoutError`.
Prompt-IO: ai/prompt-io/20261028T193020Z_b64c89f0_cached_owner.md
(this patch was generated in some part by `opencode` using
`gpt-6.1-sol` (`openai`))
`MsgStream.subscribe()` and `LinkedTaskChannel.subscribe()` omitted
`BroadcastReceiver.raise_on_lag`, forcing downstream consumers to
mutate a private receiver attribute when overruns were acceptable.
Add `raise_on_lag` to both public wrappers. The first subscription
sets the irreversible root broadcaster's policy, while every child
selects its own strict or warn/drop/resume behavior independently.
Document both fan-out APIs. Cover policy forwarding plus real IPC
and infected-asyncio paths.
Prompt-IO: ai/prompt-io/opencode/20260812T213117Z_51185487_prompt_io.md
(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
The rendered guides and executable examples still taught the legacy
`ActorNursery.run_in_actor()` result-portal model even though #481
adds its blocking, linked-context replacement.
Deats,
- migrate one-shots to direct results through `to_actor.run()`
- preserve named target inputs with `functools.partial()`
- use daemon actors where reciprocal dialogs need longer lifetimes
- link the new API from core, asyncio and clustering references
- retain only explicit legacy/removal notes
Prompt-IO: ai/prompt-io/opencode/20260820T023005Z_88a23449_prompt_io.md
(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves#157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_prompt_io.md
(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code