diff --git a/tractor/_root.py b/tractor/_root.py index 1bcfa00b..81ff884b 100644 --- a/tractor/_root.py +++ b/tractor/_root.py @@ -217,11 +217,16 @@ async def open_root_actor( ): if enable_transports is None: enable_transports: list[str] = _state.current_ipc_protos() + else: + _state._runtime_vars['_enable_tpts'] = enable_transports - # TODO! support multi-tpts per actor! Bo - assert ( - len(enable_transports) == 1 - ), 'No multi-tpt support yet!' + # TODO! support multi-tpts per actor! + # Bo + if not len(enable_transports) == 1: + raise RuntimeError( + f'No multi-tpt support yet!\n' + f'enable_transports={enable_transports!r}\n' + ) _debug.hide_runtime_frames() __tracebackhide__: bool = hide_tb diff --git a/tractor/_runtime.py b/tractor/_runtime.py index b25f6bc1..015c235c 100644 --- a/tractor/_runtime.py +++ b/tractor/_runtime.py @@ -877,9 +877,7 @@ class Actor: return ( chan, accept_addrs, - None, - # ^TODO, preferred tpts list from rent! - # -[ ] need to extend the `SpawnSpec` tho! + _state._runtime_vars['_enable_tpts'] ) # failed to connect back? @@ -1453,10 +1451,12 @@ async def async_main( # all sub-actors should be able to speak to # their root actor over that channel. if _state._runtime_vars['_is_root']: + raddrs: list[Address] = _state._runtime_vars['_root_addrs'] for addr in accept_addrs: - waddr = wrap_address(addr) - if waddr == waddr.get_root(): - _state._runtime_vars['_root_mailbox'] = addr + waddr: Address = wrap_address(addr) + raddrs.append(addr) + else: + _state._runtime_vars['_root_mailbox'] = raddrs[0] # Register with the arbiter if we're told its addr log.runtime( diff --git a/tractor/_state.py b/tractor/_state.py index bc12d0de..4eba74f0 100644 --- a/tractor/_state.py +++ b/tractor/_state.py @@ -37,14 +37,28 @@ if TYPE_CHECKING: from ._context import Context +# default IPC transport protocol settings +TransportProtocolKey = Literal[ + 'tcp', + 'uds', +] +_def_tpt_proto: TransportProtocolKey = 'tcp' + _current_actor: Actor|None = None # type: ignore # noqa _last_actor_terminated: Actor|None = None # TODO: mk this a `msgspec.Struct`! _runtime_vars: dict[str, Any] = { '_debug_mode': False, - '_is_root': False, - '_root_mailbox': (None, None), + # root of actor-process tree info + '_is_root': False, # bool + '_root_mailbox': (None, None), # tuple[str|None, str|None] + '_root_addrs': [], # tuple[str|None, str|None] + + # parent->chld ipc protocol caps + '_enable_tpts': [_def_tpt_proto], + + # registrar info '_registry_addrs': [], '_is_infected_aio': False, @@ -172,14 +186,6 @@ def get_rt_dir( return rtdir -# default IPC transport protocol settings -TransportProtocolKey = Literal[ - 'tcp', - 'uds', -] -_def_tpt_proto: TransportProtocolKey = 'tcp' - - def current_ipc_protos() -> list[str]: ''' Return the list of IPC transport protocol keys currently @@ -189,4 +195,4 @@ def current_ipc_protos() -> list[str]: concrete-backend sub-types defined throughout `tractor.ipc`. ''' - return [_def_tpt_proto] + return _runtime_vars['_enable_tpts'] diff --git a/tractor/msg/types.py b/tractor/msg/types.py index 86752aba..aaf8d137 100644 --- a/tractor/msg/types.py +++ b/tractor/msg/types.py @@ -170,6 +170,7 @@ class SpawnSpec( # a hard `Struct` def for all of these fields! _parent_main_data: dict _runtime_vars: dict[str, Any] + # ^NOTE see `._state._runtime_vars: dict` # module import capability enable_modules: dict[str, str]