Normalize `Registrar.delete_addr()` declarations
Match deletion inputs to the canonical addresses stored by `register_actor()`. Legacy TCP/UDS pairs and the `uds` alias otherwise miss their entry and leave it registered. Cover legacy and tagged declarations as tuples and msgpack-style lists, checking the returned uid and removal of the final entry. Review: PR #505 (goodboy) https://github.com/goodboy/tractor/pull/505#pullrequestreview-5408224830 (this patch was generated in some part by `opencode` using `gpt-6-astra` (`openai`))wkt/addr_unpacking
parent
f70cfd62a6
commit
2b4b65e717
|
|
@ -157,3 +157,64 @@ def test_registrar_stores_canonical_addresses(
|
||||||
assert registrar._registry == {
|
assert registrar._registry == {
|
||||||
new_uid: [canonical],
|
new_uid: [canonical],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('container', [tuple, list])
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'declaration',
|
||||||
|
[
|
||||||
|
pytest.param(('127.0.0.1', 1616), id='legacy-tcp'),
|
||||||
|
pytest.param(
|
||||||
|
('tcp', '127.0.0.1', 1616),
|
||||||
|
id='tagged-tcp',
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
('/tmp/tractor', 'registry.sock'),
|
||||||
|
id='legacy-uds',
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
('unix', '/tmp/tractor/registry.sock'),
|
||||||
|
id='tagged-unix',
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
('uds', '/tmp/tractor/registry.sock'),
|
||||||
|
id='uds-alias',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_registrar_deletes_equivalent_address_forms(
|
||||||
|
declaration: tuple,
|
||||||
|
container: type,
|
||||||
|
):
|
||||||
|
'''
|
||||||
|
Delete a canonical registration using any accepted spelling.
|
||||||
|
|
||||||
|
``Registrar.register_actor()`` stores canonical tagged addresses,
|
||||||
|
but ``Registrar.delete_addr()`` previously compared the supplied
|
||||||
|
tuple unchanged. A legacy declaration or ``uds`` alias therefore
|
||||||
|
left a stale entry in ``Registrar._registry``. Register each
|
||||||
|
declaration, verify its stored canonical form, then delete with
|
||||||
|
the original spelling as a tuple or msgpack-style list. Returning
|
||||||
|
the registered uid and leaving no entry proves normalization at
|
||||||
|
the deletion boundary without requiring a mixed-version tree.
|
||||||
|
|
||||||
|
'''
|
||||||
|
registrar = SimpleNamespace(
|
||||||
|
_registry={},
|
||||||
|
_waiters={},
|
||||||
|
)
|
||||||
|
uid = ('service', 'service-uid')
|
||||||
|
canonical = wrap_address(declaration).unwrap()
|
||||||
|
|
||||||
|
async def register_then_delete():
|
||||||
|
await Registrar.register_actor(registrar, uid, declaration)
|
||||||
|
assert registrar._registry == {uid: [canonical]}
|
||||||
|
|
||||||
|
deleted_uid = await Registrar.delete_addr(
|
||||||
|
registrar,
|
||||||
|
container(declaration),
|
||||||
|
)
|
||||||
|
assert deleted_uid == uid
|
||||||
|
assert registrar._registry == {}
|
||||||
|
|
||||||
|
trio.run(register_then_delete)
|
||||||
|
|
|
||||||
|
|
@ -234,9 +234,9 @@ class Registrar(Actor):
|
||||||
addr: tuple[str, int|str]|list[str|int],
|
addr: tuple[str, int|str]|list[str|int],
|
||||||
) -> tuple[str, str]|None:
|
) -> tuple[str, str]|None:
|
||||||
# NOTE: `addr` arrives as a `list` over IPC
|
# NOTE: `addr` arrives as a `list` over IPC
|
||||||
# (msgpack deserializes tuples -> lists) so
|
# (msgpack deserializes tuples -> lists). Normalize legacy
|
||||||
# coerce to `tuple` for the linear scan.
|
# and tagged forms to match `Registrar._registry` entries.
|
||||||
addr = tuple(addr)
|
addr = wrap_address(addr).unwrap()
|
||||||
uid: tuple[str, str]|None = None
|
uid: tuple[str, str]|None = None
|
||||||
|
|
||||||
for _uid, addrs in self._registry.items():
|
for _uid, addrs in self._registry.items():
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue