Add `tractor.query_actor()` an addr looker-upper
Sometimes it's handy to just have a non-`Portal` yielding way to figure out if a "service" actor is up, so add this discovery helper for that. We'll prolly just leave it undocumented for now until we figure out a longer-term/better discovery system.name_query
							parent
							
								
									62983684d1
								
							
						
					
					
						commit
						80897a8f2b
					
				|  | @ -29,7 +29,12 @@ from ._streaming import ( | |||
|     stream, | ||||
|     context, | ||||
| ) | ||||
| from ._discovery import get_arbiter, find_actor, wait_for_actor | ||||
| from ._discovery import ( | ||||
|     get_arbiter, | ||||
|     find_actor, | ||||
|     wait_for_actor, | ||||
|     query_actor, | ||||
| ) | ||||
| from ._supervise import open_nursery | ||||
| from ._state import current_actor, is_root_process | ||||
| from ._exceptions import ( | ||||
|  | @ -46,11 +51,15 @@ from ._portal import Portal | |||
| __all__ = [ | ||||
|     'Channel', | ||||
|     'Context', | ||||
|     'ModuleNotExposed', | ||||
|     'MultiError', | ||||
|     'RemoteActorError', | ||||
|     'ContextCancelled', | ||||
|     'ModuleNotExposed', | ||||
|     'MsgStream', | ||||
|     'MultiError', | ||||
|     'Portal', | ||||
|     'ReceiveMsgStream', | ||||
|     'RemoteActorError', | ||||
|     'breakpoint', | ||||
|     'context', | ||||
|     'current_actor', | ||||
|     'find_actor', | ||||
|     'get_arbiter', | ||||
|  | @ -59,14 +68,11 @@ __all__ = [ | |||
|     'open_actor_cluster', | ||||
|     'open_nursery', | ||||
|     'open_root_actor', | ||||
|     'Portal', | ||||
|     'post_mortem', | ||||
|     'query_actor', | ||||
|     'run', | ||||
|     'run_daemon', | ||||
|     'stream', | ||||
|     'context', | ||||
|     'ReceiveMsgStream', | ||||
|     'MsgStream', | ||||
|     'to_asyncio', | ||||
|     'wait_for_actor', | ||||
| ] | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ Actor discovery API. | |||
| """ | ||||
| import typing | ||||
| from typing import Tuple, Optional, Union | ||||
| from async_generator import asynccontextmanager | ||||
| from contextlib import asynccontextmanager as acm | ||||
| 
 | ||||
| from ._ipc import _connect_chan, Channel | ||||
| from ._portal import ( | ||||
|  | @ -31,7 +31,7 @@ from ._portal import ( | |||
| from ._state import current_actor, _runtime_vars | ||||
| 
 | ||||
| 
 | ||||
| @asynccontextmanager | ||||
| @acm | ||||
| async def get_arbiter( | ||||
| 
 | ||||
|     host: str, | ||||
|  | @ -58,7 +58,7 @@ async def get_arbiter( | |||
|                 yield arb_portal | ||||
| 
 | ||||
| 
 | ||||
| @asynccontextmanager | ||||
| @acm | ||||
| async def get_root( | ||||
|     **kwargs, | ||||
| ) -> typing.AsyncGenerator[Portal, None]: | ||||
|  | @ -71,28 +71,56 @@ async def get_root( | |||
|             yield portal | ||||
| 
 | ||||
| 
 | ||||
| @asynccontextmanager | ||||
| async def find_actor( | ||||
| @acm | ||||
| async def query_actor( | ||||
|     name: str, | ||||
|     arbiter_sockaddr: Tuple[str, int] = None | ||||
| ) -> typing.AsyncGenerator[Optional[Portal], None]: | ||||
|     """Ask the arbiter to find actor(s) by name. | ||||
|     arbiter_sockaddr: Tuple[str, int] = None, | ||||
| 
 | ||||
|     Returns a connected portal to the last registered matching actor | ||||
|     known to the arbiter. | ||||
|     """ | ||||
| ) -> tuple[str, int]: | ||||
|     ''' | ||||
|     Simple address lookup for a given actor name. | ||||
| 
 | ||||
|     Returns the (socket) address or ``None``. | ||||
| 
 | ||||
|     ''' | ||||
|     actor = current_actor() | ||||
|     async with get_arbiter(*arbiter_sockaddr or actor._arb_addr) as arb_portal: | ||||
|     async with get_arbiter( | ||||
|         *arbiter_sockaddr or actor._arb_addr | ||||
|     ) as arb_portal: | ||||
| 
 | ||||
|         sockaddr = await arb_portal.run_from_ns('self', 'find_actor', name=name) | ||||
|         sockaddr = await arb_portal.run_from_ns( | ||||
|             'self', | ||||
|             'find_actor', | ||||
|             name=name, | ||||
|         ) | ||||
| 
 | ||||
|         # TODO: return portals to all available actors - for now just | ||||
|         # the last one that registered | ||||
|         if name == 'arbiter' and actor.is_arbiter: | ||||
|             raise RuntimeError("The current actor is the arbiter") | ||||
| 
 | ||||
|         elif sockaddr: | ||||
|         yield sockaddr if sockaddr else None | ||||
| 
 | ||||
| 
 | ||||
| @acm | ||||
| async def find_actor( | ||||
|     name: str, | ||||
|     arbiter_sockaddr: Tuple[str, int] = None | ||||
| 
 | ||||
| ) -> typing.AsyncGenerator[Optional[Portal], None]: | ||||
|     ''' | ||||
|     Ask the arbiter to find actor(s) by name. | ||||
| 
 | ||||
|     Returns a connected portal to the last registered matching actor | ||||
|     known to the arbiter. | ||||
| 
 | ||||
|     ''' | ||||
|     async with query_actor( | ||||
|         name=name, | ||||
|         arbiter_sockaddr=arbiter_sockaddr, | ||||
|     ) as sockaddr: | ||||
| 
 | ||||
|         if sockaddr: | ||||
|             async with _connect_chan(*sockaddr) as chan: | ||||
|                 async with open_portal(chan) as portal: | ||||
|                     yield portal | ||||
|  | @ -100,7 +128,7 @@ async def find_actor( | |||
|             yield None | ||||
| 
 | ||||
| 
 | ||||
| @asynccontextmanager | ||||
| @acm | ||||
| async def wait_for_actor( | ||||
|     name: str, | ||||
|     arbiter_sockaddr: Tuple[str, int] = None | ||||
|  | @ -111,9 +139,14 @@ async def wait_for_actor( | |||
|     """ | ||||
|     actor = current_actor() | ||||
| 
 | ||||
|     async with get_arbiter(*arbiter_sockaddr or actor._arb_addr) as arb_portal: | ||||
| 
 | ||||
|         sockaddrs = await arb_portal.run_from_ns('self', 'wait_for_actor', name=name) | ||||
|     async with get_arbiter( | ||||
|         *arbiter_sockaddr or actor._arb_addr, | ||||
|     ) as arb_portal: | ||||
|         sockaddrs = await arb_portal.run_from_ns( | ||||
|             'self', | ||||
|             'wait_for_actor', | ||||
|             name=name, | ||||
|         ) | ||||
|         sockaddr = sockaddrs[-1] | ||||
| 
 | ||||
|         async with _connect_chan(*sockaddr) as chan: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue