''' Demonstrate an actor tree which talks over unix-domain-socket (UDS) transport instead of the default TCP: pass `enable_transports=['uds']` when opening the root and every subactor inherits the preference. The child's channel address is a filesystem socket path (no TCP port in sight!) and, as a kernel-provided bonus, the peer's pid is exchanged for free via `SO_PEERCRED`. ''' import os import trio import tractor async def report_addr() -> str: ''' Return this actor's own accept (bind) addr + pid. ''' actor = tractor.current_actor() addr: tuple = actor.accept_addr pid: int = os.getpid() return f'{actor.name}@{addr} pid={pid}' async def main() -> None: async with tractor.open_nursery( enable_transports=['uds'], ) as an: portal = await an.start_actor( 'uds_child', enable_modules=[__name__], ) # the channel's remote addr is a `UDSAddress`: a # filesystem socket path, NOT a (host, port) pair! raddr = portal.chan.raddr assert raddr.proto_key == 'uds' print( f'portal chan tpt proto: {raddr.proto_key!r}\n' f'portal chan sock file: {raddr.sockpath}\n' f'kernel-reported peer pid: {raddr.maybe_pid}\n' ) # ask the child for its own bind addr: also a # socket-file path under the runtime dir. print(f'child says: {await portal.run(report_addr)}') await portal.cancel_actor() if __name__ == '__main__': trio.run(main)