tractor/tractor
Tyler Goodlet 6628fa00d9 Refine `MsgTypeError` handling to relay-up-on-`.recv()`
Such that `Channel.recv()` + `MsgpackTCPStream.recv()` originating
msg-type-errors are not raised at the IPC transport layer but instead
relayed up the runtime stack for eventual handling by user-app code via
the `Context`/`MsgStream` layer APIs.

This design choice leads to a substantial amount of flexibility and
modularity, and avoids `MsgTypeError` handling policies from being
coupled to a particular backend IPC transport layer:
- receive-side msg-type errors, as can be raised and handled in the
  `.open_stream()` "nasty" phase of a ctx, whilst being packed at the
  `MsgCodec`/transport layer (keeping the underlying src decode error
  coupled to the specific transport + interchange lib) and then relayed
  upward to app code for custom handling like a normal Error` msg.
- the policy options for handling such cases could be implemented as
  `@acm` wrappers around `.open_context()`/`.open_stream()` blocks (and
  their respective delivered primitives) OR just plain old async
  generators around `MsgStream.receive()` such that both built-in policy
  handling and custom user-app solutions can be swapped without touching
  any `tractor` internals or providing specialized "registry APIs".
  -> eg. the ignore and relay-invalid-msg-to-sender approach can be more
   easily implemented as embedded `try: except MsgTypeError:` blocks
   around `MsgStream.receive()` possibly applied as either of an
   injected wrapper type around a stream or an async gen that `async
   for`s from the stream.
- any performance based AOT-lang extensions used to implement a policy
  for handling recv-side errors space can avoid knowledge of the lower
  level IPC `Channel` (and-downward) primitives.
- `Context` consuming code can choose to let all msg-type-errs
  bubble and handle them manually (like any other remote `Error`
  shuttled exception).
- we can keep (as before) send-side msg type checks can be raised
  locally and cause offending senders to error and adjust before the
  streaming phase of an IPC ctx.

Impl (related) deats:
- obvi make `MsgpackTCPStream.recv()` yield up any `MsgTypeError`
  constructed by `_mk_msg_type_err()` such that the exception will
  eventually be relayed up to `._rpc.process_messages()` and from
  their delivered to the corresponding ctx-task.
- in support of ^, make `Channel.recv()` detect said mtes and use the
  new `pack_from_raise()` to inject the far end `Actor.uid` for the
  `Error.src_uid`.
- keep raising the send side equivalent (when strict enabled) errors
  inline immediately with no upward `Error` packing or relay.
- improve `_mk_msg_type_err()` cases handling with far more detailed
  `MsgTypeError` "message" contents pertaining to `msgspec` specific
  failure-fixing-tips and type-spec mismatch info:
  * use `.from_decode()` constructor in recv-side case to inject the
    non-spec decoded `msg_dict: dict` and use the new
    `MsgCodec.pld_spec_str: str` when clarifying the type discrepancy
    with the offending field.
  * on send-side, if we detect that an unsupported field type was
    described in the original `src_type_error`, AND there is no
    `msgpack.Encoder.enc_hook()` set, that the real issue is likely
    that the user needs to extend the codec to support the
    non-std/custom type with a hook and link to `msgspec` docs.
  * if one of a `src_type/validation_error` is provided, set that
    error as the `.__cause__` in the new mte.
2025-03-21 15:25:41 -04:00
..
_testing Start a new `._testing.fault_simulation` 2025-03-21 15:25:41 -04:00
devx WIP porting runtime to use `Msg`-spec 2025-03-21 15:25:41 -04:00
experimental Drop now-deprecated deps on modern `trio`/Python 2025-03-16 16:06:24 -04:00
msg Expose `MsgType` and extend `MsgCodec` API a bit 2025-03-21 15:25:41 -04:00
trionics Drop now-deprecated deps on modern `trio`/Python 2025-03-16 16:06:24 -04:00
__init__.py Expose `MsgTypeError` from pkg 2025-03-21 15:25:41 -04:00
_child.py Hide `._entry`/`._child` frames, tweak some more type annots 2025-03-20 23:22:45 -04:00
_clustering.py Passthrough runtime kwargs from `open_actor_cluster()` 2022-12-11 19:56:08 -05:00
_context.py Rename `Actor._push_result()` -> `._deliver_ctx_payload()` 2025-03-21 15:25:41 -04:00
_discovery.py More spaceless union type annots 2025-03-20 19:50:31 -04:00
_entry.py WIP porting runtime to use `Msg`-spec 2025-03-21 15:25:41 -04:00
_exceptions.py Unify `MsgTypeError` as a `RemoteActorError` subtype 2025-03-21 15:25:41 -04:00
_forkserver_override.py Re-license code base for distribution under AGPL 2021-12-14 23:33:27 -05:00
_ipc.py Refine `MsgTypeError` handling to relay-up-on-`.recv()` 2025-03-21 15:25:41 -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 Drop `None`-sentinel cancels RPC loop mechanism 2025-03-21 15:25:41 -04:00
_root.py Add `enable_stack_on_sig: bool` for `stackscope` toggle 2025-03-20 23:22:45 -04:00
_rpc.py Rename `Actor._push_result()` -> `._deliver_ctx_payload()` 2025-03-21 15:25:41 -04:00
_runtime.py Rename `Actor._push_result()` -> `._deliver_ctx_payload()` 2025-03-21 15:25:41 -04:00
_spawn.py WIP porting runtime to use `Msg`-spec 2025-03-21 15:25:41 -04:00
_state.py Add defaul rtv for `use_greeback: bool = False` 2025-03-20 23:22:45 -04:00
_streaming.py Rename `Actor._push_result()` -> `._deliver_ctx_payload()` 2025-03-21 15:25:41 -04:00
_supervise.py Hide `._entry`/`._child` frames, tweak some more type annots 2025-03-20 23:22:45 -04:00
log.py Bleh, make `log.devx()` level less then cancel but > `.runtime()` 2025-03-20 23:22:45 -04:00
to_asyncio.py Provision for infected-`asyncio` debug mode support 2025-03-20 22:37:51 -04:00