diff --git a/examples/multihost/client.py b/examples/multihost/client.py index 888b100..d4893bf 100644 --- a/examples/multihost/client.py +++ b/examples/multihost/client.py @@ -6,33 +6,45 @@ log = tractor.log.get_console_log( _root_name='my_app', name='client', ) +_loglevel: str = 'cancel' async def client_main(): # enable console logging for our custom app's logger tractor.log.get_console_log( - level='info', + level=_loglevel, _root_name='my_app', name='client', ) - # presuming you can get a ref to the target server RPC-ctx func + # presuming you can get a ref to the target server RPC-ctx func, + # pass it directly as our rpc-ctx endpoint below. from server import proxy_request + # + # NOTE, see he equiv note in `server.py` explaining why this will + # render more or less to `'server:proxy_request'` according to + # `tractor.msg.NamespacePath.from_ref(proxy_request)` async with ( tractor.open_root_actor( name='web_requester', registry_addrs=[('127.0.0.1', 1616)], enable_modules=[], # since this isn't a service actor + loglevel=_loglevel, ), # use discovery api to find the server actor on your net # (NOTE, in which case the below registry addr would have to # be the public IP of that host!) - tractor.find_actor( + # tractor.find_actor( + # name='web_proxier', + # registry_addrs=[('127.0.0.1', 1616)], + # ) as portal, + + tractor.wait_for_actor( name='web_proxier', - registry_addrs=[('127.0.0.1', 1616)], + registry_addr=('127.0.0.1', 1616), ) as portal, # open an RPC context with the remote actor, thus spawning @@ -47,4 +59,5 @@ async def client_main(): print(resp) -trio.run(client_main) +if __name__ == '__main__': + trio.run(client_main) diff --git a/examples/multihost/server.py b/examples/multihost/server.py index 8f43b58..3b4ac67 100644 --- a/examples/multihost/server.py +++ b/examples/multihost/server.py @@ -36,7 +36,8 @@ async def proxy_request( # response type for the wire directly, at least no without # a custom `msgspec.Decoder`!! return str(resp) - # + + # return resp # ^TODO, various typed msging options: # -[ ] try returning just the `resp` verbatim => should raise # an MTE @@ -53,17 +54,32 @@ async def main(): name='server_thingy', ) - # since run as a script this will likely be `__main__` - # so instead we want to just use our module name.. + # since (originally) this is run as a script, we will end up with + # `__name__ == '__main__'` so to ensure the rpc request from the + # client isn't blocked by `tractor.ModuleNotFound`, we want to just + # use the explicit file-as-module name.. why u ask? this_mod: str = 'server' + # WELP, when the `Portal.open_context()` api (used in + # `client.py`) requests the RPC-ctx ep it will send + # a `str`-like-ptr encoding the func-ref in form expected by + # `pkgutil.resolve_name()`. + # + # Since the client's local namespace reference/path to this + # `.server.py` mod will be from a direct manual import, that + # `proxy_request()`-ref will render as `'server:proxy_request'` + # (as delivered from `NamespacePath.from_ref()` since that's how + # `.open_context()` serializes the func's-ref for IPC transit). + # SO, we need to be sure we "enable" this module name so that the + # nsp maps to an enabled module in the `Actor._mods: dict`. + async with tractor.open_root_actor( name='web_proxier', registry_addrs=[('127.0.0.1', 1616)], enable_modules=[this_mod], loglevel='info', ): - # just block waiting for a peer actor to connect and open an RPC context using the above - # proxy endpoint. + # just block waiting for a peer actor to connect and open an + # RPC context using the above proxy endpoint. log.info( 'proxy server up bby!\n' 'waiting to serve some requests..\n'