Canonicalize addrs in `Registrar.register_actor()`
Store the validated `waddr.unwrap()` result so legacy and tagged declarations share one registry identity. This lets stale-entry eviction replace an older actor which used the compatibility form. Cover TCP and UDS registrations crossing from legacy to tagged addrs. Review: PR #505 (goodboy) https://github.com/goodboy/tractor/pull/505#pullrequestreview-5094473850 (this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))wkt/addr_unpacking
parent
ca436aa9ec
commit
9d1e476d04
|
|
@ -3,10 +3,13 @@ Canonical tagged-address decoding and legacy input compatibility.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import trio
|
||||||
|
|
||||||
from tractor.discovery._addr import wrap_address
|
from tractor.discovery._addr import wrap_address
|
||||||
|
from tractor.discovery._registry import Registrar
|
||||||
from tractor.ipc._tcp import TCPAddress
|
from tractor.ipc._tcp import TCPAddress
|
||||||
from tractor.ipc._uds import UDSAddress
|
from tractor.ipc._uds import UDSAddress
|
||||||
|
|
||||||
|
|
@ -98,3 +101,59 @@ def test_tcp_from_native_ipv6_sockname():
|
||||||
)
|
)
|
||||||
|
|
||||||
assert addr.unwrap() == ('tcp', '::1', 1616)
|
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
|
# should never be 0-dynamic-os-alloc
|
||||||
await debug.pause()
|
await debug.pause()
|
||||||
|
|
||||||
addr_tup: tuple = tuple(addr)
|
addr_tup: tuple = waddr.unwrap()
|
||||||
|
|
||||||
# Evict stale entries: if a *different* uid claims
|
# Evict stale entries: if a *different* uid claims
|
||||||
# this addr (e.g. after unclean shutdown or
|
# this addr (e.g. after unclean shutdown or
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue