Skip to content

🐛 repro: external resolve advances action-orchestrated loop (#1188)#1189

Closed
taras wants to merge 1 commit into
v4from
repro/1188-action-loop-external-resolve
Closed

🐛 repro: external resolve advances action-orchestrated loop (#1188)#1189
taras wants to merge 1 commit into
v4from
repro/1188-action-loop-external-resolve

Conversation

@taras

@taras taras commented Jun 12, 2026

Copy link
Copy Markdown
Member

Reproduction for #1188. These tests are expected to fail — they document the bug and should go green once the underlying fix lands.

What it shows

When shutdown is triggered externally via scope.run(() => resolve(...)) from inside an action-orchestrated loop, the loop advances into the next iteration (round-2-start) after the shutdown trigger, instead of stopping once the current iteration finishes.

Two tests are added to test/scoped.test.ts:

  1. does not advance loop after external resolve with nested scoped + race — mirrors the original report (action wrapping a loop, each round runs scoped(scoped(race(...)))). Observed events:

    round-1-start
    round-1-result:false
    round-failed-trigger-shutdown
    round-2-start        ← leaks
    
  2. does not advance loop after external resolve in minimal action baseline — strips out scoped() and race() entirely; just action + a for loop + sleep + external resolve. Still leaks:

    round-1-start
    round-failed-trigger-shutdown
    round-2-start        ← leaks
    

Why the baseline matters

The minimal baseline has no scoped and no race, yet it still advances to round-2-start. That isolates the root cause to the action + external-resolve path — i.e. resolving an action from outside (via scope.run) does not unwind the operation that is currently suspended awaiting that action before the loop takes its next step.

This is the broader category #1188 refers to: #1185 was the narrower scoped + race manifestation (fixed in #1186 / 49fe66f0), but the same "external resolve doesn't halt the in-flight iteration" problem reproduces with a plain action loop.

Run

deno test --allow-run --allow-read --allow-env --allow-ffi test/scoped.test.ts

Two failing tests reproducing #1188: when shutdown is triggered
externally via scope.run(() => resolve(...)) from inside an
action-orchestrated loop, the loop advances into the next iteration
(round-2-start) before teardown completes.

- "nested scoped + race" mirrors the original report.
- "minimal action baseline" strips out scoped() and race() entirely and
  still leaks round-2-start, isolating the root cause to the
  action + external-resolve path rather than scoped/race (the latter
  was the narrower #1185, already fixed by #1186).

These tests are expected to fail until the underlying action unwind
propagation is fixed.
@pkg-pr-new

pkg-pr-new Bot commented Jun 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/effection@1189

commit: d1e5aa6

@codspeed-hq

codspeed-hq Bot commented Jun 12, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing repro/1188-action-loop-external-resolve (d1e5aa6) with v4 (49fe66f)

Open in CodSpeed

@taras

taras commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

this is not a problem. It just shows that we can interrupt sync loop which is not expected to be possible

@taras taras closed this Jun 12, 2026
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