Fix when root-actor addrs is set as rtvs
Move `_root_addrs` assignment to after `async_main()` unblocks (via `.started()`) which now delivers the bind addrs , ensuring correct `UnwrappedAddress` propagation into `._state._runtime_vars`. Previously for non-registrar root actors the `._state._runtime_vars` entries were being set as `Address` values which serialized incorrectly to children/subactors.. This fixes the issue by waiting for the `.ipc.*` stack to bind-and-resolve any randomly allocated addrs (by the OS) until after the initial `Actor` startup is complete. Deats, - primarily, mv `_root_addrs` assignment from before `root_tn.start()` to after, using started(-ed) `accept_addrs` now delivered from `async_main()`.. - update `task_status` type hints to match. - unpack ansd set the `(accept_addrs, reg_addrs)` tuple from `root_tn.start()` call into `._state._runtime_vars` entries. - improve comments distinguishing registrar vs non-registrar init paths, ensure typing reflects wrapped vs. unwrapped addrs. Also, - add a masked `mk_pdb().set_trace()` for debugging `raddrs` values being "off". - add TODO about using UDS on linux for root mailbox - rename `trans_bind_addrs` -> `tpt_bind_addrs` for clarity. - expand comment about random port allocation for non-registrar case (this commit msg was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
parent
807d4251f6
commit
f2825fae87
|
|
@ -88,7 +88,8 @@ async def maybe_block_bp(
|
||||||
bp_blocked: bool
|
bp_blocked: bool
|
||||||
if (
|
if (
|
||||||
debug_mode
|
debug_mode
|
||||||
and maybe_enable_greenback
|
and
|
||||||
|
maybe_enable_greenback
|
||||||
and (
|
and (
|
||||||
maybe_mod := await debug.maybe_init_greenback(
|
maybe_mod := await debug.maybe_init_greenback(
|
||||||
raise_not_found=False,
|
raise_not_found=False,
|
||||||
|
|
@ -385,10 +386,13 @@ async def open_root_actor(
|
||||||
addr,
|
addr,
|
||||||
)
|
)
|
||||||
|
|
||||||
trans_bind_addrs: list[UnwrappedAddress] = []
|
tpt_bind_addrs: list[
|
||||||
|
Address # `Address.get_random()` case
|
||||||
|
|UnwrappedAddress # registrar case `= uw_reg_addrs`
|
||||||
|
] = []
|
||||||
|
|
||||||
# Create a new local root-actor instance which IS NOT THE
|
# ------ NON-REGISTRAR ------
|
||||||
# REGISTRAR
|
# create a new root-actor instance.
|
||||||
if ponged_addrs:
|
if ponged_addrs:
|
||||||
if ensure_registry:
|
if ensure_registry:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
|
|
@ -415,12 +419,21 @@ async def open_root_actor(
|
||||||
# XXX INSTEAD, bind random addrs using the same tpt
|
# XXX INSTEAD, bind random addrs using the same tpt
|
||||||
# proto.
|
# proto.
|
||||||
for addr in ponged_addrs:
|
for addr in ponged_addrs:
|
||||||
trans_bind_addrs.append(
|
tpt_bind_addrs.append(
|
||||||
|
# XXX, these are `Address` NOT `UnwrappedAddress`.
|
||||||
|
#
|
||||||
|
# NOTE, in the case of posix/berkley socket
|
||||||
|
# protos we allocate port=0 such that the system
|
||||||
|
# allocates a random value at bind time; this
|
||||||
|
# happens in the `.ipc.*` stack's backend.
|
||||||
addr.get_random(
|
addr.get_random(
|
||||||
bindspace=addr.bindspace,
|
bindspace=addr.bindspace,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ------ REGISTRAR ------
|
||||||
|
# create a new "registry providing" root-actor instance.
|
||||||
|
#
|
||||||
# Start this local actor as the "registrar", aka a regular
|
# Start this local actor as the "registrar", aka a regular
|
||||||
# actor who manages the local registry of "mailboxes" of
|
# actor who manages the local registry of "mailboxes" of
|
||||||
# other process-tree-local sub-actors.
|
# other process-tree-local sub-actors.
|
||||||
|
|
@ -429,7 +442,7 @@ async def open_root_actor(
|
||||||
# following init steps are taken:
|
# following init steps are taken:
|
||||||
# - the tranport layer server is bound to each addr
|
# - the tranport layer server is bound to each addr
|
||||||
# pair defined in provided registry_addrs, or the default.
|
# pair defined in provided registry_addrs, or the default.
|
||||||
trans_bind_addrs = uw_reg_addrs
|
tpt_bind_addrs = uw_reg_addrs
|
||||||
|
|
||||||
# - it is normally desirable for any registrar to stay up
|
# - it is normally desirable for any registrar to stay up
|
||||||
# indefinitely until either all registered (child/sub)
|
# indefinitely until either all registered (child/sub)
|
||||||
|
|
@ -449,20 +462,10 @@ async def open_root_actor(
|
||||||
enable_modules=enable_modules,
|
enable_modules=enable_modules,
|
||||||
)
|
)
|
||||||
# XXX, in case the root actor runtime was actually run from
|
# XXX, in case the root actor runtime was actually run from
|
||||||
# `tractor.to_asyncio.run_as_asyncio_guest()` and NOt
|
# `tractor.to_asyncio.run_as_asyncio_guest()` and NOT
|
||||||
# `.trio.run()`.
|
# `.trio.run()`.
|
||||||
actor._infected_aio = _state._runtime_vars['_is_infected_aio']
|
actor._infected_aio = _state._runtime_vars['_is_infected_aio']
|
||||||
|
|
||||||
# NOTE, only set the loopback addr for the
|
|
||||||
# process-tree-global "root" mailbox since all sub-actors
|
|
||||||
# should be able to speak to their root actor over that
|
|
||||||
# channel.
|
|
||||||
raddrs: list[Address] = _state._runtime_vars['_root_addrs']
|
|
||||||
raddrs.extend(trans_bind_addrs)
|
|
||||||
# TODO, remove once we have also removed all usage;
|
|
||||||
# eventually all (root-)registry apis should expect > 1 addr.
|
|
||||||
_state._runtime_vars['_root_mailbox'] = raddrs[0]
|
|
||||||
|
|
||||||
# Start up main task set via core actor-runtime nurseries.
|
# Start up main task set via core actor-runtime nurseries.
|
||||||
try:
|
try:
|
||||||
# assign process-local actor
|
# assign process-local actor
|
||||||
|
|
@ -499,14 +502,39 @@ async def open_root_actor(
|
||||||
# "actor runtime" primitives are SC-compat and thus all
|
# "actor runtime" primitives are SC-compat and thus all
|
||||||
# transitively spawned actors/processes must be as
|
# transitively spawned actors/processes must be as
|
||||||
# well.
|
# well.
|
||||||
await root_tn.start(
|
accept_addrs: list[UnwrappedAddress]
|
||||||
|
reg_addrs: list[UnwrappedAddress]
|
||||||
|
(
|
||||||
|
accept_addrs,
|
||||||
|
reg_addrs,
|
||||||
|
) = await root_tn.start(
|
||||||
partial(
|
partial(
|
||||||
_runtime.async_main,
|
_runtime.async_main,
|
||||||
actor,
|
actor,
|
||||||
accept_addrs=trans_bind_addrs,
|
accept_addrs=tpt_bind_addrs,
|
||||||
parent_addr=None
|
parent_addr=None
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
# NOTE, only set a local-host addr (i.e. like
|
||||||
|
# `lo`-loopback for TCP) for the process-tree-global
|
||||||
|
# "root"-process (its tree-wide "mailbox") since all
|
||||||
|
# sub-actors should be able to speak to their root
|
||||||
|
# actor over that channel.
|
||||||
|
#
|
||||||
|
# ?TODO, per-OS non-network-proto alt options?
|
||||||
|
# -[ ] on linux we should be able to always use UDS?
|
||||||
|
#
|
||||||
|
raddrs: list[Address] = _state._runtime_vars['_root_addrs']
|
||||||
|
raddrs.extend(
|
||||||
|
accept_addrs,
|
||||||
|
)
|
||||||
|
# TODO, remove once we have also removed all usage;
|
||||||
|
# eventually all (root-)registry apis should expect > 1 addr.
|
||||||
|
_state._runtime_vars['_root_mailbox'] = raddrs[0]
|
||||||
|
# if 'chart' in actor.aid.name:
|
||||||
|
# from tractor.devx import mk_pdb
|
||||||
|
# mk_pdb().set_trace()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield actor
|
yield actor
|
||||||
except (
|
except (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue