mstar.communication.wire#

Typed msgpack encoding for everything that crosses a communicator edge. Msgpack is readable by both Python and Rust, allowing, e.g., the sender to be fully Rust and the receiver to be Python.

The encoding is type-driven: the decoder knows the declared type of every field, so the wire carries values, not type tags, except where a field is polymorphic (see _POLYMORPHIC).

Field plans are compiled once per class into a tuple of closures; resulving annotations per message is about 17x slower than pickle.

Notes: - dict keyed by a tuple (graph_timings) becomes a list of entries. - set becomes a list and is rebuilt on decode. - PublishedInfo / ResourceReqConfig / MessageBody are abstract, so

those fields carry [tag, payload].

  • A value whose declared type says nothing useful (bare dict, Any, model_kwargs) goes as plain msgpack only when that round-trips exactly – scalars, lists, str-keyed dicts – and is pickled into an ExtType otherwise. Such fields hold whatever a model or a client put there, so converting them by hand is lossy (tuples come back as lists, int keys as pairs) or raises mid-send; pickle is what they crossed the wire as before. A Rust sender only ever splices these as opaque, already-encoded bytes.

Module Attributes

AUTO_PREFIX

Tag prefix for a dataclass reached through a loosely-typed field and never explicitly registered.

PICKLED_EXT

msgpack ext code for a pickled value from a loosely-typed field.

OPAQUE

Frame tag for a payload that is not a registered message.

Functions

decode(data)

encode(msg)

encode_field(value, hint)

One field's value, encoded as its DECLARED type, on its own.

encode_fields(values, hints)

Several field values as one msgpack array, each by its declared type.

register(tag, cls)

Register a class whose definition we do not own.

wire_type(tag)

Register a concrete class under tag for polymorphic fields.

Exceptions

mstar.communication.wire.AUTO_PREFIX = 'auto:'#

Tag prefix for a dataclass reached through a loosely-typed field and never explicitly registered. Self-describing so the decoder can find it without maintenance – the curated tags in wire_types.py stay short.

mstar.communication.wire.OPAQUE = '__py__'#

Frame tag for a payload that is not a registered message. The codec has to be total — a communicator carries whatever a caller hands it, and a codec that raises on some payloads turns into a silent hang at the receiver (the send dies, the peer waits forever). Registered messages, which are the only ones a Rust endpoint decodes, never take this path.

mstar.communication.wire.PICKLED_EXT = 80#

msgpack ext code for a pickled value from a loosely-typed field.

exception mstar.communication.wire.WireError[source]#

Bases: Exception

mstar.communication.wire.decode(data)[source]#
Parameters:

data (bytes)

mstar.communication.wire.encode(msg)[source]#
Return type:

bytes

mstar.communication.wire.encode_field(value, hint)[source]#

One field’s value, encoded as its DECLARED type, on its own.

For a sender that builds the rest of the frame elsewhere: the Rust graph runtime encodes what it owns and splices these in as opaque values, so it never has to know CurrentForwardPassInfo or grow a case for every new PublishedInfo subclass.

Passing the declared type is what makes the result safe to splice – it selects the same encoder _plan would have chosen for that field, so the frame decodes identically to having built the whole message here.

Return type:

bytes

mstar.communication.wire.encode_fields(values, hints)[source]#

Several field values as one msgpack array, each by its declared type.

For a payload that is a bare tuple of values rather than a message. encode would reach the pickle fallback on one of those – a list has no wire tag – and a pickled payload cannot be spliced into a frame the Rust runtime builds.

Return type:

bytes

mstar.communication.wire.register(tag, cls)[source]#

Register a class whose definition we do not own.

Parameters:
Return type:

None

mstar.communication.wire.wire_type(tag)[source]#

Register a concrete class under tag for polymorphic fields.

Parameters:

tag (str)