Use `Aid` keys for child reap state
The fresh reap-coordination maps still used legacy `.uid` tuples even though process monitors and channels carry complete `Aid` identities. This extended the legacy key format into new private state. Key both reap maps by `Aid` and derive `.uid` only when accessing the existing `_children` map. UUID-based `Aid` hashing lets the subactor and decoded channel identities resolve the same synchronization state. Update registration tests to exercise the full identity keys. Review: PR #481 (goodboy) https://github.com/goodboy/tractor/pull/481#pullrequestreview-5012942328 Prompt-IO: ai/prompt-io/opencode/20260824T233957Z_5327b25e_prompt_io.md (this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))wkt/to_actor_subpkg
parent
5327b25e1b
commit
e42ecb559d
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
model: openai/gpt-5.6-sol
|
||||||
|
service: opencode
|
||||||
|
session: d9d7df2c-7044-463f-8768-ec024718eac9
|
||||||
|
timestamp: 2026-08-24T23:39:57Z
|
||||||
|
git_ref: 5327b25e
|
||||||
|
scope: code
|
||||||
|
substantive: true
|
||||||
|
raw_file: 20260824T233957Z_5327b25e_prompt_io.raw.md
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
Continue PR #481 review remediation after committing the debugger-state
|
||||||
|
sampler. The human selected "keep" for the paired review request to use
|
||||||
|
`Aid` objects as keys in the newly added reap-coordination maps.
|
||||||
|
|
||||||
|
## Response summary
|
||||||
|
|
||||||
|
Migrate only `ActorNursery._child_reap_requests` and
|
||||||
|
`ActorNursery._child_reaped` to `Aid` keys. Preserve the legacy
|
||||||
|
`ActorNursery._children` `.uid` key and pass full actor identities
|
||||||
|
through the narrow process-monitor bookkeeping path.
|
||||||
|
|
||||||
|
## Files changed
|
||||||
|
|
||||||
|
- `tractor/runtime/_supervise.py` - key fresh reap maps by `Aid`.
|
||||||
|
- `tractor/spawn/_spawn.py` - pass `Aid` into completed-reap cleanup.
|
||||||
|
- `tests/test_to_actor.py` - exercise `Aid` registration keys.
|
||||||
|
|
||||||
|
## Human edits
|
||||||
|
|
||||||
|
The human explicitly selected "keep" after reviewing the scope,
|
||||||
|
performance, and mutability tradeoffs. The human retained the legacy
|
||||||
|
tuple key for `_children` and accepted `Aid` for only the two fresh
|
||||||
|
private mappings. No direct source-line edits were made by the human.
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
model: openai/gpt-5.6-sol
|
||||||
|
service: opencode
|
||||||
|
timestamp: 2026-08-24T23:39:57Z
|
||||||
|
git_ref: 5327b25e
|
||||||
|
diff_cmd: git diff HEAD~1..HEAD
|
||||||
|
---
|
||||||
|
|
||||||
|
Implement the approved PR #481 review update which uses `Aid` keys for
|
||||||
|
the two fresh `ActorNursery` reap-coordination maps while preserving the
|
||||||
|
legacy `.uid` key for `ActorNursery._children`.
|
||||||
|
|
||||||
|
> `git diff HEAD~1..HEAD -- tractor/runtime/_supervise.py`
|
||||||
|
|
||||||
|
Type and access `_child_reap_requests` and `_child_reaped` by `Aid`.
|
||||||
|
Pass full actor identities through registration, cancellation, and
|
||||||
|
completed-reap bookkeeping, deriving `.uid` only for `_children`.
|
||||||
|
|
||||||
|
> `git diff HEAD~1..HEAD -- tractor/spawn/_spawn.py`
|
||||||
|
|
||||||
|
Forward `subactor.aid` when publishing completed process teardown.
|
||||||
|
|
||||||
|
> `git diff HEAD~1..HEAD -- tests/test_to_actor.py`
|
||||||
|
|
||||||
|
Update deterministic registration tests to exercise `Aid` map keys.
|
||||||
|
|
||||||
|
Run focused registration/reaping tests and the full `to_actor` suite.
|
||||||
|
|
@ -431,8 +431,8 @@ def test_late_child_registration_observes_cancel():
|
||||||
proc,
|
proc,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
assert an._child_reap_requests[aid.uid] is reap_request
|
assert an._child_reap_requests[aid] is reap_request
|
||||||
assert an._child_reaped[aid.uid] is reaped
|
assert an._child_reaped[aid] is reaped
|
||||||
|
|
||||||
|
|
||||||
def test_mp_late_registration_never_starts_process(
|
def test_mp_late_registration_never_starts_process(
|
||||||
|
|
@ -521,9 +521,11 @@ def test_late_child_reap_registration_is_released():
|
||||||
an._child_reaped = {}
|
an._child_reaped = {}
|
||||||
|
|
||||||
an._join_procs.set()
|
an._join_procs.set()
|
||||||
reap_request, _ = an._register_child_reap(
|
aid = tractor.msg.Aid(
|
||||||
('late_child', 'uid'),
|
name='late_child',
|
||||||
|
uuid='uid',
|
||||||
)
|
)
|
||||||
|
reap_request, _ = an._register_child_reap(aid)
|
||||||
|
|
||||||
assert reap_request.is_set()
|
assert reap_request.is_set()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ from ..log import (
|
||||||
get_logger,
|
get_logger,
|
||||||
get_loglevel,
|
get_loglevel,
|
||||||
)
|
)
|
||||||
|
from ..msg import Aid
|
||||||
from ._runtime import Actor
|
from ._runtime import Actor
|
||||||
from ._portal import Portal
|
from ._portal import Portal
|
||||||
from ..trionics import (
|
from ..trionics import (
|
||||||
|
|
@ -246,11 +247,11 @@ class ActorNursery:
|
||||||
|
|
||||||
self._join_procs = trio.Event()
|
self._join_procs = trio.Event()
|
||||||
self._child_reap_requests: dict[
|
self._child_reap_requests: dict[
|
||||||
tuple[str, str],
|
Aid,
|
||||||
trio.Event,
|
trio.Event,
|
||||||
] = {}
|
] = {}
|
||||||
self._child_reaped: dict[
|
self._child_reaped: dict[
|
||||||
tuple[str, str],
|
Aid,
|
||||||
trio.Event,
|
trio.Event,
|
||||||
] = {}
|
] = {}
|
||||||
self._at_least_one_child_in_debug: bool = False
|
self._at_least_one_child_in_debug: bool = False
|
||||||
|
|
@ -319,7 +320,7 @@ class ActorNursery:
|
||||||
|
|
||||||
def _register_child_reap(
|
def _register_child_reap(
|
||||||
self,
|
self,
|
||||||
uid: tuple[str, str],
|
aid: Aid,
|
||||||
) -> tuple[trio.Event, trio.Event]:
|
) -> tuple[trio.Event, trio.Event]:
|
||||||
'''
|
'''
|
||||||
Register a child monitor's process-reap events.
|
Register a child monitor's process-reap events.
|
||||||
|
|
@ -327,8 +328,8 @@ class ActorNursery:
|
||||||
'''
|
'''
|
||||||
reap_request = trio.Event()
|
reap_request = trio.Event()
|
||||||
reaped = trio.Event()
|
reaped = trio.Event()
|
||||||
self._child_reap_requests[uid] = reap_request
|
self._child_reap_requests[aid] = reap_request
|
||||||
self._child_reaped[uid] = reaped
|
self._child_reaped[aid] = reaped
|
||||||
if self._join_procs.is_set():
|
if self._join_procs.is_set():
|
||||||
reap_request.set()
|
reap_request.set()
|
||||||
return reap_request, reaped
|
return reap_request, reaped
|
||||||
|
|
@ -343,13 +344,14 @@ class ActorNursery:
|
||||||
Atomically publish one child and its reap coordination.
|
Atomically publish one child and its reap coordination.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
uid: tuple[str, str] = subactor.aid.uid
|
aid: Aid = subactor.aid
|
||||||
|
uid: tuple[str, str] = aid.uid
|
||||||
self._children[uid] = (
|
self._children[uid] = (
|
||||||
subactor,
|
subactor,
|
||||||
proc,
|
proc,
|
||||||
portal,
|
portal,
|
||||||
)
|
)
|
||||||
reap_request, reaped = self._register_child_reap(uid)
|
reap_request, reaped = self._register_child_reap(aid)
|
||||||
return (
|
return (
|
||||||
reap_request,
|
reap_request,
|
||||||
reaped,
|
reaped,
|
||||||
|
|
@ -369,18 +371,19 @@ class ActorNursery:
|
||||||
|
|
||||||
def _mark_child_reaped(
|
def _mark_child_reaped(
|
||||||
self,
|
self,
|
||||||
uid: tuple[str, str],
|
aid: Aid,
|
||||||
) -> None:
|
) -> None:
|
||||||
'''
|
'''
|
||||||
Publish completed child-process teardown to its waiter.
|
Publish completed child-process teardown to its waiter.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
uid: tuple[str, str] = aid.uid
|
||||||
self._children.pop(uid, None)
|
self._children.pop(uid, None)
|
||||||
reap_request: trio.Event|None = (
|
reap_request: trio.Event|None = (
|
||||||
self._child_reap_requests.pop(uid, None)
|
self._child_reap_requests.pop(aid, None)
|
||||||
)
|
)
|
||||||
reaped: trio.Event|None = self._child_reaped.pop(
|
reaped: trio.Event|None = self._child_reaped.pop(
|
||||||
uid,
|
aid,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
|
|
@ -399,14 +402,15 @@ class ActorNursery:
|
||||||
Cancel, join and unregister one nursery-owned child.
|
Cancel, join and unregister one nursery-owned child.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
uid: tuple[str, str] = portal.channel.aid.uid
|
aid: Aid = portal.channel.aid
|
||||||
|
uid: tuple[str, str] = aid.uid
|
||||||
child_entry = self._children.get(uid)
|
child_entry = self._children.get(uid)
|
||||||
if child_entry is None:
|
if child_entry is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
subactor, proc, _ = child_entry
|
subactor, proc, _ = child_entry
|
||||||
reap_request: trio.Event = self._child_reap_requests[uid]
|
reap_request: trio.Event = self._child_reap_requests[aid]
|
||||||
reaped: trio.Event = self._child_reaped[uid]
|
reaped: trio.Event = self._child_reaped[aid]
|
||||||
|
|
||||||
with trio.CancelScope(shield=True):
|
with trio.CancelScope(shield=True):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -460,7 +460,7 @@ async def new_proc(
|
||||||
proc_kwargs=proc_kwargs
|
proc_kwargs=proc_kwargs
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
actor_nursery._mark_child_reaped(subactor.aid.uid)
|
actor_nursery._mark_child_reaped(subactor.aid)
|
||||||
|
|
||||||
|
|
||||||
# NOTE: bottom-of-module to avoid a circular import since the
|
# NOTE: bottom-of-module to avoid a circular import since the
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue