Skip to content

fix(effect-ts): await Effect cleanup during Effection scope teardown#178

Open
taras wants to merge 1 commit intomainfrom
fix/effect-ts-cancellation-with-alpha
Open

fix(effect-ts): await Effect cleanup during Effection scope teardown#178
taras wants to merge 1 commit intomainfrom
fix/effect-ts-cancellation-with-alpha

Conversation

@taras
Copy link
Member

@taras taras commented Mar 6, 2026

Motivation

When upgrading to effection 4.1.0-alpha.7 (needed monorepo-wide for scope.around() and createApi() APIs required by @effectionx/durable-streams), two @effectionx/effect-ts tests started failing:

  • "interrupts Effect when Effection task is halted" — Effect finalizer hadn't run by assertion time
  • "cleans up Effect resources when Effection scope halts"acquireRelease cleanup incomplete

The root cause: action() teardown calls controller.abort() synchronously, but Effect's cleanup (finalizers, acquireRelease) runs asynchronously through promises. The scope destruction proceeds before Effect's promise chain settles.

Approach

  • Track in-flight Effect executions in a Set<PendingExecution> within the resource scope
  • During resource teardown (finally block), abort all pending executions and yield* until() their settlement before disposing the ManagedRuntime
  • Gate reject-path propagation from action() when the abort signal is already triggered, preventing spurious FiberFailure errors from reaching Effection
  • Add monorepo-wide pnpm.overrides for effection: "4.1.0-alpha.7" to enable the alpha APIs

All 27 effect-ts tests pass. The 4 remaining failures in the full suite (exec/watch) are pre-existing and unrelated.

Summary by CodeRabbit

  • Refactor
    • Enhanced execution tracking and lifecycle management for in-flight operations.
    • Improved runtime shutdown process with proper abort handling and promise settlement for all active executions.
    • Strengthened cleanup logic to ensure all pending executions are properly terminated before runtime disposal.

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Warning

Rate limit exceeded

@taras has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 23 minutes and 14 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ac2a7d07-bce5-4117-acef-023504483ba5

📥 Commits

Reviewing files that changed from the base of the PR and between 3aaf6f1 and daeef22.

📒 Files selected for processing (2)
  • effect-ts/effect-runtime.ts
  • effect-ts/package.json
📝 Walkthrough

Walkthrough

Adds execution tracking and abort capabilities to the Effect runtime. Introduces a pending execution set with startManaged utility to manage AbortControllers. Refactors run and runExit functions to use this tracking, and enhances the finally block to abort all active executions before cleanup.

Changes

Cohort / File(s) Summary
Effect Runtime Abort Tracking
effect-ts/effect-runtime.ts
Introduces PendingExecution type and pending Set for tracking in-flight executions. Adds startManaged utility to create AbortController-based wrappers. Reworks run and runExit to register executions and capture promise/abort/signal. Updates finally block to abort all pending executions and wait for settlement before disposal.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Policy Compliance ❌ Error The package.json contains non-approved keywords ('effection', 'effectionx', 'effect-ts', 'effect') violating the Package.json Metadata policy (Strict). Update keywords field to only include approved keywords: 'interop' and/or 'concurrency'. Remove all custom keywords.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(effect-ts): await Effect cleanup during Effection scope teardown' is concise and clearly describes the main change—ensuring Effect cleanup completes before scope teardown finishes.
Description check ✅ Passed The pull request description fully adheres to the template with a comprehensive Motivation section explaining the race condition and an Approach section detailing all implementation changes and testing results.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/effect-ts-cancellation-with-alpha

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 6, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@effectionx/effect-ts@178

commit: 1480c22

@taras taras requested a review from joshamaju March 6, 2026 01:57
@taras taras force-pushed the fix/effect-ts-cancellation-with-alpha branch from b2f2862 to 3aaf6f1 Compare March 6, 2026 01:59
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
effect-ts/effect-runtime.ts (1)

98-188: ⚠️ Potential issue | 🔴 Critical

Bump version in effect-ts/package.json.

Per .policies/version-bump.md, source code changes to published packages require a semantic version bump. The changes to effect-runtime.ts (runtime behavior modifications) must be accompanied by a version increment in effect-ts/package.json.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@effect-ts/effect-runtime.ts` around lines 98 - 188, The package version for
the published package must be bumped to reflect the runtime changes in
makeEffectRuntime; open effect-ts/package.json and increment the "version" field
following semver (patch/minor/major as appropriate for the breaking/non-breaking
change), update any related lockfiles if required, and commit the updated
package.json so the change to effect-runtime.ts (function makeEffectRuntime and
its runtime behavior) is released with a new package version.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@effect-ts/effect-runtime.ts`:
- Around line 98-188: The package version for the published package must be
bumped to reflect the runtime changes in makeEffectRuntime; open
effect-ts/package.json and increment the "version" field following semver
(patch/minor/major as appropriate for the breaking/non-breaking change), update
any related lockfiles if required, and commit the updated package.json so the
change to effect-runtime.ts (function makeEffectRuntime and its runtime
behavior) is released with a new package version.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0d85b57b-c637-4cc3-b002-5d234929a175

📥 Commits

Reviewing files that changed from the base of the PR and between 022418e and b2f2862.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • effect-ts/effect-runtime.ts
  • package.json

@taras taras force-pushed the fix/effect-ts-cancellation-with-alpha branch from 3aaf6f1 to 904e824 Compare March 6, 2026 02:04
When an Effection scope is halted, the action() teardown calls
controller.abort() synchronously, but Effect's cleanup (finalizers,
acquireRelease) runs asynchronously through promises. This can cause
tests to see incomplete cleanup.

Fix: Track in-flight Effect executions in a Set. During resource
teardown, abort all pending executions and await their settlement
before disposing the ManagedRuntime. Gate reject-path propagation
from action() when the abort signal is already triggered to prevent
spurious FiberFailure errors from reaching Effection.
Comment on lines +169 to +170
if (!signal.aborted) {
reject(error);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runExit should never cause the parent to fail/throw. The action should resolve with an Exit.failCause of an unknown error or something like that.

https://effect.website/docs/data-types/exit/

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.

2 participants