fix(act): arm drain flag on reset so settled apps replay#609
Merged
fix(act): arm drain flag on reset so settled apps replay#609
Conversation
Add Act.reset(streams) that wraps store().reset() and sets _needs_drain when the orchestrator has reactive events. Calling store().reset() directly leaves the flag untouched, so a settled app short-circuits in drain()/settle() and silently skips the replay. Updates docs, scaffold-act-app skill, and the calculator rebuild demo to recommend app.reset(...) over store().reset(...). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related fixes for the reset/replay flow: 1. settle() default maxPasses changed from 1 → Infinity. 2. settle() exit condition rewritten: stop when a pass makes no progress (no new subscriptions AND no acks AND no blocks), rather than the previous "exit when correlate finds no new subs on i>0" — which bailed out before draining paginated work. Together this means a single app.settle() after app.reset(...) fully catches up streams of any length, with no caller-side loop. maxPasses remains as a kill-switch for runaway reaction chains. Updates docs (CLAUDE.md, README, libs/act/README, PERFORMANCE.md) and the scaffold-act-app skill to drop manual drain loops in favor of the single-call pattern. The previous "should break early when correlate returns no subscriptions on second pass" test asserted the old buggy behavior — replaced with a regression test that fixes paginated drain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
🎉 This PR is included in version @rotorsoft/act-v0.30.1 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes for the reset/replay flow on the orchestrator:
Act.reset(streams)— wrapsstore().reset(...)and arms the orchestrator's internal_needs_drainflag. Callingstore().reset(...)directly leaves the flag untouched, so a settled app short-circuits indrain()/settle()and silently skips the replay.settle()drains to completion by default —maxPassesdefault changed from1→Infinity, and the loop now exits on "no progress" (no new subscriptions AND no acks AND no blocks). The previous early-exit bailed out before draining paginated work whenevercorrelatereturned 0 subs on iteration > 0.maxPassesremains as a kill-switch for runaway reaction chains.Together: a single
await app.reset([...])followed byapp.settle()(or onedrain()for small streams) fully catches up paginated streams of any length, with no caller-side loop.Reproducer
Two new tests in
libs/act/test/rebuild.spec.tsexercise the full settle-then-reset path. Both fail on master and pass with this fix:should replay events when drain runs after reset on a settled appshould replay events when settle runs after reset on a settled appThe pre-existing
act.spec.tstest "should break early when correlate returns no subscriptions on second pass" was asserting the old buggy paginated-drain behavior — replaced with a regression test that proves settle keeps draining as long as drain is still acking.Docs / pattern
Updated to consistently recommend
app.reset(...)+settle():CLAUDE.md§ Projection RebuildREADME.md§ Projections Are Disposablelibs/act/README.md§ Settle (debounce + completion semantics)libs/act/PERFORMANCE.md(reflects new maxPasses default)Store.resetJSDoc points atAct.resetas the high-level API.claude/skills/scaffold-act-app/act-api.md— new § 15 plus updated settle docs.claude/skills/scaffold-act-app/server.md— drops manualmaxPasses: 10Test plan
npx vitest run)pnpm typecheckcleanpnpm buildclean🤖 Generated with Claude Code