tractor/tractor
Tyler Goodlet bc9faac218 Init def of "SC shuttle prot" with "msg-spec-limiting"
As per the long outstanding GH issue this starts our rigorous journey
into an attempt at a type-safe, cross-actor SC, IPC protocol Bo

boop -> https://github.com/goodboy/tractor/issues/36

The idea is to "formally" define our SC "shuttle (dialog) protocol" by
specifying a new `.msg.types.Msg` subtype-set which can fully
encapsulate all IPC msg schemas needed in order to accomplish
cross-process SC!

------ - ------

The msg set deviated a little in terms of (type) names from the existing
`dict`-msgs currently used in the runtime impl but, I think the msg name
changes are much better in terms of explicitly representing the internal
semantics of the actor runtime machinery subsystems and IPC-msg-dialog
required for SC enforced RPC. In cursory, the new formal msgs-spec
includes the following msg-subtypes of a new top-level `Msg` boxing type
(that holds the base field schema for all msgs):

- `Start` to request RPC task scheduling by passing a `FuncSpec`
  payload (implemented currently with a `{'cmd': ... }` dict msg)

- `StartAck` to allow the RPC task callee-side to report a `IpcCtxSpec`
  payload immediately back to the caller (currently done naively via
  a `{'functype': ... }` initial response msg)

- `Started` to deliver the first value from `Context.started()`
  (instead of existing `{'started': ... }`)

- `Yield` to shuttle `MsgStream.send()`-ed values (currently
  `{'yield': ... }`s)

- `Stop` to terminate a `Context.open_stream()` session/block (currently
  a `{'stop': True }`)

- `Return` to deliver the final value from the `Actor.start_remote_task()`
  remote task (instead of `{'return': ... }`)

- `Error` to box `RemoteActorError` exceptions via a `.pld: ErrorData`
  payload, also planned to replace/extend the current
  `RemoteActorError.msgdata` mechanism internal to `pack/unpack_error()`

The new `tractor.msg.types` includes all these msg defs as well an API
for rendering a "payload msg specification" using a `payload_type_spec:
Union[Type]` that can be passed to
`msgspec.msgpack.Decoder(type=payload_type_spec)`. This ensures that
(per msg relevant) `Msg.pld: PayloadT` data is type-parameterized using
`msgspec`'s new `Generic[PayloadT]` field support and thus enables
providing for an API where IPC `Context` dialogs can strictly define the
allowed payload-msg-set by a type union!

Iow, this is the foundation for supporting `Channel`/`Context`/`MsgStream`
IPC primitives which are type checked/safe as desired in GH issue:
- https://github.com/goodboy/tractor/issues/365

Misc notes on current impl(s) status:
------ - ------
- add a `.msg.types.mk_msg_spec()` which uses the new `msgspec` support
  for `class MyStruct[Struct, Generic[T]]` parameterize-able fields and
  delivers our boxing SC-msg-(sub)set with the desired `payload_types`
  applied to `.pld`:
  - https://jcristharif.com/msgspec/supported-types.html#generic-types
  - as a note this impl seems to need to use `type.new_class()` dynamic
    subtype generation, though i don't really get *why* still.. but
    without that the `msgspec.msgpack.Decoder` doesn't seem to reject
    `.pld` limited `Msg` subtypes as demonstrated in the new test.

- around this ^ add a `.msg._codec.limit_msg_spec()` cm which exposes
  this payload type limiting API such that it can be applied per task
  via a `MsgCodec` in app code.

- the orig approach in https://github.com/goodboy/tractor/pull/311 was
  the idea of making payload fields `.pld: Raw` wherein we could have
  per-field/sub-msg decoders dynamically loaded depending on the
  particular application-layer schema in use. I don't want to lose the
  idea of this since I think it might be useful for an idea I have about
  capability-based-fields(-sharing, maybe using field-subset
  encryption?), and as such i've kept the (ostensibly) working impls in
  TODO-comments in `.msg._codec` wherein maybe we can add
  a `MsgCodec._payload_decs: dict` table for this later on.
  |_ also left in the `.msg.types.enc/decmsg()` impls but renamed as
    `enc/dec_payload()` (but reworked to not rely on the lifo codec
    stack tables; now removed) such that we can prolly move them to
    `MsgCodec` methods in the future.

- add an unused `._codec.mk_tagged_union_dec()` helper which was
  originally factored out the #311 proto-code but didn't end up working
  as desired with the new parameterized generic fields approach (now
  in `msg.types.mk_msg_spec()`)

Testing/deps work:
------ - ------
- new `test_limit_msgspec()` which ensures all the `.types` content is
  correct but without using the wrapping APIs in `._codec`; i.e. using
  a in-line `Decoder` instead of a `MsgCodec`.

- pin us to `msgspec>=0.18.5` which has the needed generic-types support
  (which took me way too long yester to figure out when implementing all
  this XD)!
2024-03-28 10:45:01 -04:00
..
_testing Add (back) a `tractor._testing` sub-pkg 2024-03-13 09:09:08 -04:00
devx Provision for infected-`asyncio` debug mode support 2024-03-25 16:09:32 -04:00
experimental Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
msg Init def of "SC shuttle prot" with "msg-spec-limiting" 2024-03-28 10:45:01 -04:00
trionics Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
__init__.py Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
_child.py ._child: remove some unused imports.. 2024-01-02 10:24:39 -05:00
_clustering.py Passthrough runtime kwargs from `open_actor_cluster()` 2022-12-11 19:56:08 -05:00
_context.py Add todo-notes for hiding `@acm` frames 2024-03-24 16:49:07 -04:00
_discovery.py More spaceless union type annots 2024-03-11 10:33:06 -04:00
_entry.py `._entry`: use same msg info in start/terminate log 2024-03-05 12:30:34 -05:00
_exceptions.py Lul, don't overwrite 'tb_str' with src actor's.. 2024-03-20 11:36:39 -04:00
_forkserver_override.py Re-license code base for distribution under AGPL 2021-12-14 23:33:27 -05:00
_ipc.py WIP tagged union message type API 2024-03-26 17:25:17 -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 Move `Portal.open_context()` impl to `._context` 2024-03-13 12:09:38 -04:00
_root.py Refine and test `tractor.pause_from_sync()` 2024-03-22 19:58:25 -04:00
_rpc.py Refine and test `tractor.pause_from_sync()` 2024-03-22 19:58:25 -04:00
_runtime.py Change all `| None` -> `|None` in `._runtime` 2024-03-25 14:15:36 -04:00
_shm.py Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
_spawn.py Drop now-deprecated deps on modern `trio`/Python 2024-03-13 18:41:24 -04:00
_state.py Add a `._state._runtime_vars['_registry_addrs']` 2024-03-08 15:34:20 -05:00
_streaming.py Re-think, `msgspec`-multi-typed msg dialogs 2024-03-26 17:39:06 -04:00
_supervise.py Drop extra newline from log msg 2024-03-25 15:03:33 -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