Commit Graph

1 Commits (b6316ed776f5533044bdefe138418fda44315000)

Author SHA1 Message Date
Gud Boi 4dfcf6f660 to_asyncio: fix `trio`-side-exit handling
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`))
2026-10-29 17:28:20 -04:00