Widen `UnwrappedAddress` to admit proto-keyed addrs
`SpawnSpec.reg_addrs`/`.bind_addrs` pinned the wire shape to
a 2-tuple, so a `tipc` addr (`('tipc', stype, inst, scope)`)
died at the child w/ `msgspec.ValidationError: Expected array
of length 2, got 4` -> `invalid SpawnSpec IPC msg`.
Point those fields at `UnwrappedAddress` (which `SpawnSpec`s
own TODO already asked for) and widen the alias.
XXX VARIADIC (`tuple[str|int, ...]`) rather than a union of
the two concrete shapes, bc `msgspec` refuses a union holding
more than one array-like type.
?TODO, the real fix is the full proto-key migration (contract
§1.1) after which this becomes a tagged union keyed off elem
0 and per-proto validation comes back.
Note the alias is declared TWICE — `.msg.types` re-declares it
to dodge a circular import (`._addr` -> `.ipc._tcp` -> `.msg`)
and *that* copy is what actually validates the wire msg.
(this patch was generated in some part by `claude-code` using `claude-opus-5` (`anthropic`))
wkt/pr493_review
parent
8c0ae140cd
commit
2204979492
|
|
@ -65,9 +65,22 @@ log = get_logger()
|
||||||
#
|
#
|
||||||
UnwrappedAddress = (
|
UnwrappedAddress = (
|
||||||
# tcp/udp/uds
|
# tcp/udp/uds
|
||||||
|
# ('127.0.0.1', 1616)
|
||||||
|
# ('/run/user/1000/tractor', 'registry@1616.sock')
|
||||||
|
#
|
||||||
|
# ..and the explicitly proto-keyed (`multiaddr`-spelled)
|
||||||
|
# form, which is where ALL backends should eventually land
|
||||||
|
# per the note below,
|
||||||
|
# ('tipc', 1953628160, 1616, 2)
|
||||||
|
#
|
||||||
|
# XXX VARIADIC bc `msgspec` refuses a union of >1 array-like
|
||||||
|
# type, so the two shapes can't be spelled as a union. Keep
|
||||||
|
# in sync with `.msg.types.UnwrappedAddress` which
|
||||||
|
# re-declares this to dodge a circular import AND is what
|
||||||
|
# actually validates the `SpawnSpec` wire msg!
|
||||||
tuple[
|
tuple[
|
||||||
str, # host/domain(tcp), filesys-dir(uds)
|
str|int,
|
||||||
int|str, # port/path(uds)
|
...,
|
||||||
]
|
]
|
||||||
# ?TODO? should we also include another 2 fields from
|
# ?TODO? should we also include another 2 fields from
|
||||||
# our `Aid` msg such that we include the runtime `Actor.uid`
|
# our `Aid` msg such that we include the runtime `Actor.uid`
|
||||||
|
|
@ -82,6 +95,7 @@ UnwrappedAddress = (
|
||||||
class Address(Protocol):
|
class Address(Protocol):
|
||||||
proto_key: ClassVar[str]
|
proto_key: ClassVar[str]
|
||||||
unwrapped_type: ClassVar[UnwrappedAddress]
|
unwrapped_type: ClassVar[UnwrappedAddress]
|
||||||
|
|
||||||
# whether `.ipc._server.Endpoint.start_listener()` should
|
# whether `.ipc._server.Endpoint.start_listener()` should
|
||||||
# reconcile a bound `.addr` against its listener's
|
# reconcile a bound `.addr` against its listener's
|
||||||
# `socket.getsockname()`.
|
# `socket.getsockname()`.
|
||||||
|
|
@ -182,7 +196,7 @@ class Address(Protocol):
|
||||||
|
|
||||||
_address_types: bidict[str, Type[Address]] = {
|
_address_types: bidict[str, Type[Address]] = {
|
||||||
'tcp': TCPAddress,
|
'tcp': TCPAddress,
|
||||||
'uds': UDSAddress
|
'uds': UDSAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,31 @@ class Aid(
|
||||||
__repr__ = pretty_struct.Struct.__repr__
|
__repr__ = pretty_struct.Struct.__repr__
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE, mirrors `.discovery._addr.UnwrappedAddress` but is
|
||||||
|
# re-declared here to dodge the circular import
|
||||||
|
# (`._addr` -> `.ipc._tcp` -> `.msg`).
|
||||||
|
#
|
||||||
|
# XXX this is the **wire** shape, so widening it is a wire-format
|
||||||
|
# change; keep the two decls in sync.
|
||||||
|
# XXX VARIADIC on purpose! `msgspec` rejects a union holding
|
||||||
|
# more than one array-like type ("Type unions may not contain
|
||||||
|
# more than one array-like (list, set, tuple) type"), so the two
|
||||||
|
# concrete shapes,
|
||||||
|
#
|
||||||
|
# ('127.0.0.1', 1616) # tcp
|
||||||
|
# ('/run/user/1000/tractor', 'x.sock') # uds
|
||||||
|
# ('tipc', 1953628160, 1616, 2) # proto-keyed (tipc)
|
||||||
|
#
|
||||||
|
# can't be spelled as `tuple[str, str|int]|tuple[str, int, int,
|
||||||
|
# int]`. Widen to one homogeneous variadic tuple instead.
|
||||||
|
#
|
||||||
|
# ?TODO, the real fix is the `UnwrappedAddress` proto-key
|
||||||
|
# migration (see `.discovery._addr`) after which this becomes a
|
||||||
|
# tagged union keyed off elem 0 and full per-proto validation
|
||||||
|
# comes back.
|
||||||
|
UnwrappedAddress = tuple[str|int, ...]
|
||||||
|
|
||||||
|
|
||||||
class SpawnSpec(
|
class SpawnSpec(
|
||||||
pretty_struct.Struct,
|
pretty_struct.Struct,
|
||||||
tag=True,
|
tag=True,
|
||||||
|
|
@ -213,8 +238,8 @@ class SpawnSpec(
|
||||||
|
|
||||||
# TODO: not just sockaddr pairs?
|
# TODO: not just sockaddr pairs?
|
||||||
# -[ ] abstract into a `TransportAddr` type?
|
# -[ ] abstract into a `TransportAddr` type?
|
||||||
reg_addrs: list[tuple[str, str|int]]
|
reg_addrs: list[UnwrappedAddress]
|
||||||
bind_addrs: list[tuple[str, str|int]]|None
|
bind_addrs: list[UnwrappedAddress]|None
|
||||||
|
|
||||||
|
|
||||||
# TODO: caps based RPC support in the payload?
|
# TODO: caps based RPC support in the payload?
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue