tractor/tractor
Tyler Goodlet 5eb9144921 First draft "payload receiver in a new `.msg._ops`
As per much tinkering, re-designs and preceding rubber-ducking via many
"commit msg novelas", **finally** this adds the (hopefully) final
missing layer for typed msg safety: `tractor.msg._ops.PldRx`

(or `PayloadReceiver`? haven't decided how verbose to go..)

Design justification summary:
      ------ - ------
- need a way to be as-close-as-possible to the `tractor`-application
  such that when `MsgType.pld: PayloadT` validation takes place, it is
  straightforward and obvious how user code can decide to handle any
  resulting `MsgTypeError`.
- there should be a common and optional-yet-modular way to modify
  **how** data delivered via IPC (possibly embedded as user defined,
  type-constrained `.pld: msgspec.Struct`s) can be handled and processed
  during fault conditions and/or IPC "msg attacks".
- support for nested type constraints within a `MsgType.pld` field
  should be simple to define, implement and understand at runtime.
- a layer between the app-level IPC primitive APIs
  (`Context`/`MsgStream`) and application-task code (consumer code of
  those APIs) should be easily customized and prove-to-be-as-such
  through demonstrably rigorous internal (sub-sys) use!
  -> eg. via seemless runtime RPC eps support like `Actor.cancel()`
  -> by correctly implementing our `.devx._debug.Lock` REPL TTY mgmt
    dialog prot, via a dead simple payload-as-ctl-msg-spec.

There are some fairly detailed doc strings included so I won't duplicate
that content, the majority of the work here is actually somewhat of
a factoring of many similar blocks that are doing more or less the same
`msg = await Context._rx_chan.receive()` with boilerplate for
`Error`/`Stop` handling via `_raise_from_no_key_in_msg()`. The new
`PldRx` basically provides a shim layer for this common "receive msg,
decode its payload, yield it up to the consuming app task" by pairing
the RPC feeder mem-chan with a msg-payload decoder and expecting IPC API
internals to use **one** API instead of re-implementing the same pattern
all over the place XD

`PldRx` breakdown
 ------ - ------
- for now only expects a `._msgdec: MsgDec` which allows for
  override-able `MsgType.pld` validation and most obviously used in
  the impl of `.dec_msg()`, the decode message method.
- provides multiple mem-chan receive options including:
 |_ `.recv_pld()` which does the e2e operation of receiving a payload
    item.
 |_ a sync `.recv_pld_nowait()` version.
 |_ a `.recv_msg_w_pld()` which optionally allows retreiving both the
    shuttling `MsgType` as well as it's `.pld` body for use cases where
    info on both is important (eg. draining a `MsgStream`).

Dirty internal changeover/implementation deatz:
             ------ - ------
- obvi move over all the IPC "primitives" that previously had the duplicate recv-n-yield
  logic:
 - `MsgStream.receive[_nowait]()` delegating instead to the equivalent
   `PldRx.recv_pld[_nowait]()`.
 - add `Context._pld_rx: PldRx`, created and passed in by
   `mk_context()`; use it for the `.started()` -> `first: Started`
   retrieval inside `open_context_from_portal()`.
 - all the relevant `Portal` invocation methods: `.result()`,
   `.run_from_ns()`, `.run()`; also allows for dropping `_unwrap_msg()`
   and `.Portal_return_once()` outright Bo
- rename `Context.ctx._recv_chan` -> `._rx_chan`.
- add detailed `Context._scope` info for logging whether or not it's
  cancelled inside `_maybe_cancel_and_set_remote_error()`.
- move `._context._drain_to_final_msg()` -> `._ops.drain_to_final_msg()`
  since it's really not necessarily ctx specific per say, and it does
  kinda fit with "msg operations" more abstractly ;)
2024-04-24 00:59:41 -04:00
..
_testing Start a new `._testing.fault_simulation` 2024-04-03 10:19:50 -04:00
devx Start a `devx._code` mod 2024-04-18 15:12:32 -04:00
experimental Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
msg First draft "payload receiver in a new `.msg._ops` 2024-04-24 00:59:41 -04:00
trionics Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
__init__.py Expose `MsgTypeError` from pkg 2024-04-05 16:32:15 -04:00
_child.py Hide `._entry`/`._child` frames, tweak some more type annots 2024-04-14 17:49:18 -04:00
_clustering.py Passthrough runtime kwargs from `open_actor_cluster()` 2022-12-11 19:56:08 -05:00
_context.py First draft "payload receiver in a new `.msg._ops` 2024-04-24 00:59:41 -04:00
_discovery.py More spaceless union type annots 2024-03-11 10:33:06 -04:00
_entry.py Hide `._entry`/`._child` frames, tweak some more type annots 2024-04-14 17:49:18 -04:00
_exceptions.py Move `MsgTypeError` maker func to `._exceptions` 2024-04-22 18:24:02 -04:00
_forkserver_override.py Re-license code base for distribution under AGPL 2021-12-14 23:33:27 -05:00
_ipc.py Move `MsgTypeError` maker func to `._exceptions` 2024-04-22 18:24:02 -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.. 2023-11-06 15:44:21 -05:00
_portal.py First draft "payload receiver in a new `.msg._ops` 2024-04-24 00:59:41 -04:00
_root.py Use `DebugStatus` around subactor lock requests 2024-04-18 13:53:08 -04:00
_rpc.py TOSQUASH 77a15eb use `DebugStatus` in `._rpc` 2024-04-18 15:18:29 -04:00
_runtime.py First draft "payload receiver in a new `.msg._ops` 2024-04-24 00:59:41 -04:00
_shm.py Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
_spawn.py Hide `._entry`/`._child` frames, tweak some more type annots 2024-04-14 17:49:18 -04:00
_state.py Tweak `current_actor()` failure msg 2024-04-18 15:41:06 -04:00
_streaming.py First draft "payload receiver in a new `.msg._ops` 2024-04-24 00:59:41 -04:00
_supervise.py Annotate nursery and portal methods for `CallerInfo` scanning 2024-04-18 15:17:50 -04:00
log.py .log: more multi-line styling 2024-02-20 13:22:44 -05:00
to_asyncio.py Provision for infected-`asyncio` debug mode support 2024-03-25 16:09:32 -04:00