tractor/tractor
Tyler Goodlet 08fa266de4 Add per-side graceful-exit/cancel excs-as-signals
Such that any combination of task terminations/exits can be explicitly
handled and "dual side independent" crash cases re-raised in egs.

The main error-or-exit impl changes include,

- use of new per-side "signaling exceptions":
  - TrioTaskExited|TrioCancelled for signalling aio.
  - AsyncioTaskExited|AsyncioCancelled for signalling trio.

- NOT overloading the `LinkedTaskChannel._trio/aio_err` fields for
  err-as-signal relay and instead add a new pair of
  `._trio/aio_to_raise` maybe-exc-attrs which allow each side's
  task to specify what it would want the other side to raise to signal
  its/a termination outcome:
  - `._trio_to_raise: AsyncioTaskExited|AsyncioCancelled` to signal,
    |_ the aio task having returned while the trio side was still reading
       from the `asyncio.Queue` or is just not `.done()`.
    |_ the aio task being self or trio-request cancelled where
       a `asyncio.CancelledError` is raised and caught but NOT relayed
       as is back to trio; instead signal a "more explicit" exc type.
  - `._aio_to_raise: TrioTaskExited|TrioCancelled` to signal,
    |_ the trio task having returned while the aio side was still reading
       from the mem chan and indicating that the trio side might not
       care any more about future streamed values (like the
       `Stop/EndOfChannel` equivs for ipc `Context`s).
    |_ when the trio task canceld we do
        a `asyncio.Future.set_exception(TrioTaskExited())` to indicate
        to the aio side verbosely that it should cancel due to the trio
        parent.
  - `_aio/trio_err` are now left to only capturing the **actual**
    per-side task excs for introspection / other side's handling logic.

- supporting "graceful exits" depending on API in use from
  `translate_aio_errors()` such that if either side exits but the other
  side isn't expect to consume the final `return`ed value, we just exit
  silently, which required:
  - adding a `suppress_graceful_exits: bool` flag.
  - adjusting the `maybe_raise_aio_side_err()` logic to use that flag
    and suppress only on certain combos of `._trio_to_raise/._trio_err`.
  - prefer to raise `._trio_to_raise` when the aio-side is the src and
    vice versa.

- filling out pedantic logging for cancellation cases indicating which
  side is the cause.

- add a `LinkedTaskChannel._aio_result` modelled after our
  `Context._result` a a similar `.wait_for_result()` interface which
  allows maybe accessing the aio task's final return value if desired
  when using the `open_channel_from()` API.

- rename `cancel_trio()` done handler -> `signal_trio_when_done()`

Also some fairly major test suite updates,
- add a `delay: int` producing fixture which delivers a much larger
  timeout whenever `debug_mode` is set so that the REPL can be used
  without a surrounding cancel firing.
- add a new `test_aio_exits_early_relays_AsyncioTaskExited` including
  a paired `exit_early: bool` flag to `push_from_aio_task()`.
- adjust `test_trio_closes_early_causes_aio_checkpoint_raise` to expect
  a `to_asyncio.TrioTaskExited`.
2025-03-22 14:29:54 -04:00
..
_testing Disable tb colors in `._testing.mk_cmd()` 2025-03-22 14:29:54 -04:00
devx Handle egs on failed `request_root_stdio_lock()` 2025-03-22 14:29:54 -04:00
experimental Drop now-deprecated deps on modern `trio`/Python 2025-03-16 16:06:24 -04:00
msg Draft a (pretty)`Struct.fields_diff()` 2025-03-22 14:24:53 -04:00
trionics A couple more loose-egs flag flips 2025-03-22 14:29:54 -04:00
__init__.py Expose `._state.debug_mode()` predicate at top level 2025-03-22 14:29:54 -04:00
_child.py Hide `._entry`/`._child` frames, tweak some more type annots 2025-03-20 23:22:45 -04:00
_clustering.py Clean up some imports in `._clustering` 2025-03-22 14:29:54 -04:00
_context.py Log format tweaks for sclang reprs 2025-03-22 14:29:54 -04:00
_discovery.py Finally implement peer-lookup optimization.. 2025-03-21 15:25:55 -04:00
_entry.py Log format tweaks for sclang reprs 2025-03-22 14:29:54 -04:00
_exceptions.py Add per-side graceful-exit/cancel excs-as-signals 2025-03-22 14:29:54 -04:00
_forkserver_override.py Re-license code base for distribution under AGPL 2021-12-14 23:33:27 -05:00
_ipc.py More formal `TransportClosed` reporting/raising 2025-03-21 15:25:55 -04:00
_mp_fixup_main.py Avoid importing mp for as long as possible 2022-02-17 11:55:26 -05:00
_multiaddr.py Fix doc string "its" typo.. 2025-03-20 19:50:31 -04:00
_portal.py A couple more loose-egs flag flips 2025-03-22 14:29:54 -04:00
_root.py Expose `hide_tb: bool` from `.open_nursery()` 2025-03-22 14:29:54 -04:00
_rpc.py Log format tweaks for sclang reprs 2025-03-22 14:29:54 -04:00
_runtime.py Log format tweaks for sclang reprs 2025-03-22 14:29:54 -04:00
_spawn.py Log format tweaks for sclang reprs 2025-03-22 14:29:54 -04:00
_state.py Pass `infect_asyncio` setting via runtime-vars 2025-03-22 14:24:53 -04:00
_streaming.py Reraise RAEs in `MsgStream.receive()`; truncate tbs 2025-03-21 15:25:55 -04:00
_supervise.py Expose `hide_tb: bool` from `.open_nursery()` 2025-03-22 14:29:54 -04:00
log.py Support passing pre-conf-ed `Logger` 2025-03-22 14:24:53 -04:00
to_asyncio.py Add per-side graceful-exit/cancel excs-as-signals 2025-03-22 14:29:54 -04:00