tractor/examples/uds_transport_actor_tree.py

54 lines
1.5 KiB
Python
Raw Normal View History

'''
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)