-
Notifications
You must be signed in to change notification settings - Fork 14
Make find_actor() delete stale sockaddr entries from registrar on OSError
#366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
03f458a
149b800
a0d3741
0dfa6f4
528012f
403c217
d929fb7
850219f
85457cb
b557ec2
e71eec0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,7 +60,7 @@ | |
| async def get_registry( | ||
| addr: UnwrappedAddress|None = None, | ||
| ) -> AsyncGenerator[ | ||
| Portal | LocalPortal | None, | ||
| Portal|LocalPortal|None, | ||
| None, | ||
| ]: | ||
| ''' | ||
|
|
@@ -153,7 +153,7 @@ async def query_actor( | |
| regaddr: UnwrappedAddress|None = None, | ||
|
|
||
| ) -> AsyncGenerator[ | ||
| UnwrappedAddress|None, | ||
| tuple[UnwrappedAddress|None, Portal|None], | ||
| None, | ||
| ]: | ||
|
Comment on lines
155
to
158
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Updated the docstring to document the new
|
||
| ''' | ||
|
|
@@ -167,15 +167,16 @@ async def query_actor( | |
| actor: Actor = current_actor() | ||
| if ( | ||
| name == 'registrar' | ||
| and actor.is_registrar | ||
| and | ||
| actor.is_registrar | ||
|
Comment on lines
174
to
+176
|
||
| ): | ||
| raise RuntimeError( | ||
| 'The current actor IS the registry!?' | ||
| ) | ||
|
|
||
| maybe_peers: list[Channel]|None = get_peer_by_name(name) | ||
| if maybe_peers: | ||
| yield maybe_peers[0].raddr | ||
| yield maybe_peers[0].raddr, None | ||
| return | ||
|
|
||
| reg_portal: Portal | ||
|
|
@@ -188,8 +189,7 @@ async def query_actor( | |
| 'find_actor', | ||
| name=name, | ||
| ) | ||
| yield addr | ||
|
|
||
| yield addr, reg_portal | ||
|
|
||
| @acm | ||
| async def maybe_open_portal( | ||
|
|
@@ -204,15 +204,44 @@ async def maybe_open_portal( | |
| async with query_actor( | ||
| name=name, | ||
| regaddr=addr, | ||
| ) as addr: | ||
| pass | ||
| ) as (addr, reg_portal): | ||
| if not addr: | ||
| yield None | ||
| return | ||
|
|
||
| if addr: | ||
| async with _connect_chan(addr) as chan: | ||
| async with open_portal(chan) as portal: | ||
| yield portal | ||
| else: | ||
| yield None | ||
| try: | ||
| async with _connect_chan(addr) as chan: | ||
| async with open_portal(chan) as portal: | ||
| yield portal | ||
|
|
||
| # most likely we were unable to connect the | ||
| # transport and there is likely a stale entry in | ||
| # the registry actor's table, thus we need to | ||
| # instruct it to clear that stale entry and then | ||
| # more silently (pretend there was no reason but | ||
| # to) indicate that the target actor can't be | ||
| # contacted at that addr. | ||
| except OSError: | ||
| # NOTE: ensure we delete the stale entry | ||
| # from the registrar actor when available. | ||
| if reg_portal is not None: | ||
| uid: tuple[str, str] = await reg_portal.run_from_ns( | ||
|
||
| 'self', | ||
| 'delete_addr', | ||
| addr=addr, | ||
| ) | ||
| log.warning( | ||
| f'Deleted stale registry entry !\n' | ||
| f'addr: {addr!r}\n' | ||
| f'uid: {uid!r}\n' | ||
| ) | ||
| else: | ||
| log.warning( | ||
| f'Connection to {addr!r} failed' | ||
| f' and no registry portal available' | ||
| f' to delete stale entry.' | ||
| ) | ||
| yield None | ||
|
|
||
|
|
||
| @acm | ||
|
|
@@ -280,7 +309,7 @@ async def find_actor( | |
| if not any(portals): | ||
| if raise_on_none: | ||
| raise RuntimeError( | ||
| f'No actor "{name}" found registered @ {registry_addrs}' | ||
| f'No actor {name!r} found registered @ {registry_addrs!r}' | ||
| ) | ||
| yield None | ||
| return | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,6 +68,7 @@ | |
| from types import ModuleType | ||
| import warnings | ||
|
|
||
| from bidict import bidict | ||
| import trio | ||
| from trio._core import _run as trio_runtime | ||
| from trio import ( | ||
|
|
@@ -1920,10 +1921,10 @@ def __init__( | |
| **kwargs, | ||
| ) -> None: | ||
|
|
||
| self._registry: dict[ | ||
| self._registry: bidict[ | ||
| tuple[str, str], | ||
| UnwrappedAddress, | ||
| ] = {} | ||
| ] = bidict({}) | ||
| self._waiters: dict[ | ||
| str, | ||
| # either an event to sync to receiving an actor uid (which | ||
|
|
@@ -2012,7 +2013,8 @@ async def register_actor( | |
| # should never be 0-dynamic-os-alloc | ||
| await debug.pause() | ||
|
|
||
| self._registry[uid] = addr | ||
| # XXX NOTE, value must also be hashable. | ||
| self._registry[uid] = tuple(addr) | ||
|
||
|
|
||
| # pop and signal all waiter events | ||
| events = self._waiters.pop(name, []) | ||
|
|
@@ -2029,4 +2031,26 @@ async def unregister_actor( | |
| uid = (str(uid[0]), str(uid[1])) | ||
| entry: tuple = self._registry.pop(uid, None) | ||
| if entry is None: | ||
| log.warning(f'Request to de-register {uid} failed?') | ||
| log.warning( | ||
| f'Request to de-register {uid!r} failed?' | ||
| ) | ||
|
|
||
| async def delete_addr( | ||
| self, | ||
| addr: tuple[str, int|str], | ||
| ) -> tuple[str, str]|None: | ||
| uid: tuple | None = self._registry.inverse.pop( | ||
| addr, | ||
| None, | ||
| ) | ||
| if uid: | ||
| report: str = 'Deleting registry-entry for,\n' | ||
| else: | ||
| report: str = 'No registry entry for,\n' | ||
|
|
||
| log.warning( | ||
| report | ||
| + | ||
| f'{addr!r}@{uid!r}' | ||
| ) | ||
| return uid | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point - added explicit
registry_addrs=[reg_addr]to both theopen_nursery()andfind_actor()calls so the test is guaranteed to use the remote registrar daemon started by thedaemonfixture.