Compare commits
3 Commits
ca436aa9ec
...
bc132f0b4c
| Author | SHA1 | Date |
|---|---|---|
|
|
bc132f0b4c | |
|
|
8e428527ff | |
|
|
9d1e476d04 |
|
|
@ -14,10 +14,11 @@ transport may currently be enabled per actor.
|
|||
:margin:
|
||||
:alt: layered runtime stack from app code down to transports
|
||||
|
||||
Addresses are "unwrapped" tuples at the API edges:
|
||||
``('host', port)`` for TCP, filesystem-path pairs for UDS. For
|
||||
the full layering story — transport protocols, the IPC server,
|
||||
address types and the msg loop — see
|
||||
Address declarations still accept the legacy ``(host, port)``
|
||||
TCP pair and ``(directory, filename)`` UDS pair. Wrapped addresses
|
||||
emit canonical, protocol-tagged tuples: ``('tcp', host, port)``
|
||||
and ``('unix', path)``. For the full layering story — transport
|
||||
protocols, the IPC server, address types and the msg loop — see
|
||||
:doc:`/explain/architecture`.
|
||||
|
||||
.. currentmodule:: tractor
|
||||
|
|
|
|||
|
|
@ -104,17 +104,24 @@ msg-spec *is* the protocol, which is exactly what lets payloads
|
|||
be type-limited per-context (see ``pld_spec`` in
|
||||
:doc:`/guide/context`).
|
||||
|
||||
Addresses come in two spellings:
|
||||
Address declarations and serialized values have distinct spellings:
|
||||
|
||||
- *unwrapped*: the plain-tuple form you pass to user APIs —
|
||||
``('127.0.0.1', 1616)`` for tcp, or a
|
||||
- *legacy declarations*: the plain tuples accepted from existing
|
||||
callers — ``('127.0.0.1', 1616)`` for tcp, or a
|
||||
``(<filedir>, <filename>)`` path-pair for uds;
|
||||
- *canonical serialized values*: protocol-tagged tuples emitted by
|
||||
address objects — ``('tcp', '127.0.0.1', 1616)`` and
|
||||
``('unix', <path>)``;
|
||||
- *wrapped*: the internal ``TCPAddress``/``UDSAddress`` struct
|
||||
types (plus libp2p-style multiaddr helpers over in
|
||||
``tractor.discovery``).
|
||||
|
||||
You only ever need the tuple form; the runtime wraps and
|
||||
unwraps at the boundaries.
|
||||
The runtime accepts either declaration spelling, wraps it at the
|
||||
boundary and emits the canonical tagged form.
|
||||
|
||||
Actors sharing a registrar are expected to run the same Tractor
|
||||
version; the runtime does not negotiate address formats between
|
||||
versions.
|
||||
|
||||
TCP: the boring default
|
||||
***********************
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ async def main():
|
|||
registry_addrs=[addr.overlay],
|
||||
enable_transports=[addr.overlay.proto_key],
|
||||
) as an:
|
||||
overlay_host, _ = addr.unwrap()
|
||||
_, overlay_host, _ = addr.unwrap()
|
||||
await an.start_actor(
|
||||
'echo_srv',
|
||||
bind_addrs=[(overlay_host, 0)],
|
||||
bind_addrs=[('tcp', overlay_host, 0)],
|
||||
enable_transports=[addr.overlay.proto_key],
|
||||
enable_modules=['host_a_srv'],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Add transparent ``TunnelledAddress`` declarations for WireGuard
|
||||
multiaddrs and emit canonical protocol-tagged TCP and Unix transport
|
||||
addresses. Legacy untagged address pairs remain accepted as inputs.
|
||||
|
|
@ -3,10 +3,13 @@ Canonical tagged-address decoding and legacy input compatibility.
|
|||
|
||||
'''
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
import trio
|
||||
|
||||
from tractor.discovery._addr import wrap_address
|
||||
from tractor.discovery._registry import Registrar
|
||||
from tractor.ipc._tcp import TCPAddress
|
||||
from tractor.ipc._uds import UDSAddress
|
||||
|
||||
|
|
@ -98,3 +101,59 @@ def test_tcp_from_native_ipv6_sockname():
|
|||
)
|
||||
|
||||
assert addr.unwrap() == ('tcp', '::1', 1616)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'legacy, canonical',
|
||||
[
|
||||
(
|
||||
('127.0.0.1', 1616),
|
||||
('tcp', '127.0.0.1', 1616),
|
||||
),
|
||||
(
|
||||
('/tmp/tractor', 'registry.sock'),
|
||||
('unix', '/tmp/tractor/registry.sock'),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_registrar_stores_canonical_addresses(
|
||||
legacy: tuple,
|
||||
canonical: tuple,
|
||||
):
|
||||
'''
|
||||
Normalize registrar entries before stale-address eviction.
|
||||
|
||||
During the tagged-address migration an older actor can register
|
||||
an untagged address before a newer actor reuses that endpoint with
|
||||
its canonical tag. Store the first declaration canonically, then
|
||||
register the tagged spelling under another uid. The old uid must
|
||||
be evicted and the registry must retain exactly one canonical
|
||||
address for the replacement actor.
|
||||
|
||||
'''
|
||||
registrar = SimpleNamespace(
|
||||
_registry={},
|
||||
_waiters={},
|
||||
)
|
||||
old_uid = ('old', 'old-uid')
|
||||
new_uid = ('new', 'new-uid')
|
||||
|
||||
async def register_both():
|
||||
await Registrar.register_actor(
|
||||
registrar,
|
||||
old_uid,
|
||||
legacy,
|
||||
)
|
||||
assert registrar._registry[old_uid] == [canonical]
|
||||
|
||||
await Registrar.register_actor(
|
||||
registrar,
|
||||
new_uid,
|
||||
canonical,
|
||||
)
|
||||
|
||||
trio.run(register_both)
|
||||
|
||||
assert registrar._registry == {
|
||||
new_uid: [canonical],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ class Registrar(Actor):
|
|||
# should never be 0-dynamic-os-alloc
|
||||
await debug.pause()
|
||||
|
||||
addr_tup: tuple = tuple(addr)
|
||||
addr_tup: tuple = waddr.unwrap()
|
||||
|
||||
# Evict stale entries: if a *different* uid claims
|
||||
# this addr (e.g. after unclean shutdown or
|
||||
|
|
|
|||
Loading…
Reference in New Issue