Compare commits

..

No commits in common. "bc132f0b4c44e611730d89bbd2626cbfd5c9376e" and "ca436aa9ec1c3fd34829037f010c36b44c57e1a8" have entirely different histories.

6 changed files with 12 additions and 82 deletions

View File

@ -14,11 +14,10 @@ transport may currently be enabled per actor.
:margin:
:alt: layered runtime stack from app code down to transports
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
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
:doc:`/explain/architecture`.
.. currentmodule:: tractor

View File

@ -104,24 +104,17 @@ msg-spec *is* the protocol, which is exactly what lets payloads
be type-limited per-context (see ``pld_spec`` in
:doc:`/guide/context`).
Address declarations and serialized values have distinct spellings:
Addresses come in two spellings:
- *legacy declarations*: the plain tuples accepted from existing
callers — ``('127.0.0.1', 1616)`` for tcp, or a
- *unwrapped*: the plain-tuple form you pass to user APIs —
``('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``).
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.
You only ever need the tuple form; the runtime wraps and
unwraps at the boundaries.
TCP: the boring default
***********************

View File

@ -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=[('tcp', overlay_host, 0)],
bind_addrs=[(overlay_host, 0)],
enable_transports=[addr.overlay.proto_key],
enable_modules=['host_a_srv'],
)

View File

@ -1,3 +0,0 @@
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.

View File

@ -3,13 +3,10 @@ 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
@ -101,59 +98,3 @@ 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],
}

View File

@ -184,7 +184,7 @@ class Registrar(Actor):
# should never be 0-dynamic-os-alloc
await debug.pause()
addr_tup: tuple = waddr.unwrap()
addr_tup: tuple = tuple(addr)
# Evict stale entries: if a *different* uid claims
# this addr (e.g. after unclean shutdown or