Typed messaging: tractor.msg#
All inter-actor communication rides a small, strictly-typed
msgpack wire protocol built from msgspec.Struct types —
the “SC-shuttle” protocol that powers contexts, streams, RPC and
cancellation. You normally never touch these msg types directly
(the Context API speaks them for you) but you
do use this subpackage to define payload type contracts: per
endpoint via @tractor.context(pld_spec=...) or per channel via
custom codecs.
Violations of an active msg-spec surface as
MsgTypeError (see Errors and cancellation types); the full
typed-payload workflow is shown in examples/typed_payloads.py.
The protocol message set#
|
An abstract payload boxing/shuttling IPC msg type. |
|
Actor-identity msg. |
|
Initial runtime spec handed down from a spawning parent to its child subactor immediately following first contact via an Aid msg. |
|
Initial request to remotely schedule an RPC trio.Task via Actor.start_remote_task(). |
|
Init response to a Cmd request indicating the far end's RPC spec, namely its callable "type". |
|
Packet to shuttle the "first value" delivered by Context.started(value: Any) from a @tractor.context decorated IPC endpoint. |
|
Per IPC transmission of a value from await MsgStream.send(<value>). |
|
Stream termination signal much like an IPC version of StopAsyncIteration. |
|
Final return <value> from a remotely scheduled func-as-trio.Task. |
|
Deliver the bool return-value from a cancellation Actor method scheduled via and prior RPC request. |
|
A pkt that wraps RemoteActorErrors for relay and raising. |
Aid (identity handshake) and SpawnSpec (parent -> child
init) run at connection setup; Start/StartAck initiate an
RPC task; Started/Yield/Stop/Return are the
Context dialog phases; CancelAck and
Error close the loop on cancellation and (boxed) failure.
Msg is a legacy alias of PayloadMsg. The union of all of
the above is exported as MsgType (also __msg_spec__).
Define our strictly typed IPC message spec for the SCIPP:
that is,
the “Structurred-Concurrency-Inter-Process-(dialog)-(un)Protocol”.
Codec construction and override#
- tractor.msg.mk_codec(ipc_pld_spec=<class 'msgspec.Raw'>, libname='msgspec', enc_hook=None, ext_types=None, ext_dec=None)[source]#
Convenience factory for creating codecs eventually meant to be interchange lib agnostic (i.e. once we support more then just msgspec ;).
- class tractor.msg.MsgCodec(_enc, _dec, _pld_spec, lib=<module 'msgspec' from '/home/runner/work/tractor/tractor/.venv/lib/python3.14/site-packages/msgspec/__init__.py'>, _buf=<factory>)[source]#
A IPC msg interchange format lib’s encoder + decoder pair.
Pretty much nothing more then delegation to underlying msgspec.<interchange-protocol>.Encoder/Decoders for now.
- Parameters:
_enc (Encoder)
_dec (Decoder)
lib (ModuleType)
_buf (bytearray)
- encode(py_obj, use_buf=False, as_ext_type=False, hide_tb=True)[source]#
Encode input python objects to msgpack bytes for transfer on a tranport protocol connection.
When use_buf == True use the output buffer optimization: https://jcristharif.com/msgspec/perf-tips.html#reusing-an-output-buffer
- tractor.msg.mk_dec(spec, dec_hook=None, ext_types=None)[source]#
Create an IPC msg decoder, a slightly higher level wrapper around a msgspec.msgpack.Decoder which provides,
easier introspection of the underlying type spec via the .spec and .spec_str attrs,
.hook access to the Decoder.dec_hook(),
automatic custom extension-types decode support when dec_hook() is provided such that any PayloadMsg.pld tagged as a type from from ext_types (presuming the MsgCodec.encode() also used a .enc_hook()) is processed and constructed by a PldRx implicitily.
NOTE, as mentioned a MsgDec is normally used for PayloadMsg.pld: PayloadT field decoding inside an IPC-ctx-oriented PldRx.
- class tractor.msg.MsgDec(_dec)[source]#
An IPC msg (payload) decoder.
Normally used to decode only a payload: MsgType.pld: PayloadT field before delivery to IPC consumer code.
- Parameters:
_dec (Decoder)
- tractor.msg.apply_codec(codec, ctx=None)[source]#
Dynamically apply a MsgCodec to the current task’s runtime context such that all (of a certain class of payload containing i.e. MsgType.pld: PayloadT) IPC msgs are processed with it for that task.
Uses a contextvars.ContextVar to ensure the scope of any codec setting matches the current Context or ._rpc.process_messages() feeder task’s prior setting without mutating any surrounding scope.
When a ctx is supplied, only mod its Context.pld_codec.
matches the @cm block and DOES NOT change to the original (default) value in new tasks (as it does for ContextVar).
- tractor.msg.current_codec()[source]#
Return the current trio.Task.context’s value for msgspec_codec used by Channel.send/.recv() for wire serialization.
- Return type:
Note
apply_codec() swaps the codec via a
contextvars.ContextVar — the override only applies to
the current task (and tasks it starts), not sibling tasks
already running in the actor. Payload-decoding is layered: the
outer codec leaves .pld fields as msgspec.Raw and each
context’s payload-receiver decodes them against its spec
(the “cheap-or-nasty” validation pattern).
Namespace pointers#
- class tractor.msg.NamespacePath[source]#
A serializeable str-subtype implementing a “namespace pointer” to any Python object reference (like a function) using the same format as the built-in pkgutil.resolve_name() system.
A value describes a target’s module-path and namespace-key separated by a ‘:’ and thus can be easily used as a IPC-message-native reference-type allowing memory isolated actors to point-and-load objects via a minimal str value.
The 'module.path:obj_name' str-subtype used to
address every RPC target function over the wire (same format as
pkgutil.resolve_name()).
Pretty structs#
- class tractor.msg.Struct[source]#
Bases:
StructA “human friendlier” (aka repl buddy) struct subtype.
A msgspec.Struct subtype with a multi-line pretty
__repr__ — handy as a base for your own IPC payload types so
crash logs stay readable.
See also
Contexts and streaming for where pld_spec typing plugs into
the @context decorator, Errors and cancellation types for
MsgTypeError semantics, and
Typed messaging for the guided typed-messaging tour.