Skip to content

fix(actor): do not false-orphan the current process own running actors on registry init#1724

Merged
wqymi merged 4 commits into
mainfrom
fix/registry-false-orphan
Jul 14, 2026
Merged

fix(actor): do not false-orphan the current process own running actors on registry init#1724
wqymi merged 4 commits into
mainfrom
fix/registry-false-orphan

Conversation

@wqymi

@wqymi wqymi commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause: Layer.effect in registry.ts unconditionally UPDATEd ALL pending/running actors to idle+failure on every registry layer construction (lines 403-417). This killed actors that were registered by the very same process, not leftover rows from a dead one.

  • Fix: each layer instance now generates a unique instanceID on construction. Actors registered during that instance carry its ID in the instance_id column. Orphan recovery now only touches rows whose instance_id != current instanceID, so actors belonging to the live process are left alone.

Changes

  • Add instance_id column to actor_registry (migration + schema)
  • Store instance_id in register()
  • Rewrite orphan recovery WHERE clause to filter by instance_id != current
  • Add test: same-instance running actor is NOT orphaned
  • Existing cross-instance orphan test continues to pass

Verification

  • bun typecheck exits 0
  • All 26 actor registry tests pass (including new test)

wqymi added 4 commits July 14, 2026 20:44
…s on registry init

Root cause: Layer.effect's make body unconditionally UPDATEd ALL
pending/running actors to idle+failure on every registry layer
construction (L403-417). This killed actors that were registered by the
very same process, not leftover rows from a dead one.

Fix: each layer instance generates a unique instanceID on construction.
Actors registered during that instance carry its ID. Orphan recovery now
only touches rows whose instance_id != current instanceID, so actors
belonging to the live process are left alone.

Changes:
- Add instance_id column to actor_registry (migration + schema)
- Store instance_id in register()
- Rewrite orphan recovery WHERE clause to filter by instance_id != current
- Add test: same-instance running actor is NOT orphaned
- Existing cross-instance orphan test continues to pass
…e orphaning on layer rebuild

Move PROCESS_INSTANCE_ID out of Layer.effect to module level so it is
computed once per process (from process.pid + hrtime) rather than
regenerated on each layer construction. This prevents layer rebuilds
within the same process from false-orphaning their own running children.

Add tests verifying:
- Same-process layer rebuild does NOT orphan running children
- Rows from different instanceIDs ARE correctly orphaned
…t isolation

#1724 changed orphan recovery to only mark rows whose instance_id differs
from the current process. Since PROCESS_INSTANCE_ID is a process-level
constant, same-process test leftovers survive orphan recovery. This causes
listActive() to return stale rows, breaking assertions in:

- 'listActive > returns empty list when no active tasks'
- 'renderRebuildContext v3 > returns empty when no memory or tasks'

(Both fail only when run after other actor tests, not in isolation.)

Fix: add beforeEach hooks that delete all actor_registry rows, restoring
the test isolation that the unconditional orphan recovery previously
provided.
@wqymi wqymi merged commit 4923e8e into main Jul 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant