Skip to content

fix: wait for active dev rebuilds and watcher cleanup on shutdown - #206

Open
AmanVarshney01 wants to merge 3 commits into
mainfrom
codex/fix-dev-shutdown
Open

AmanVarshney01 wants to merge 3 commits into
mainfrom
codex/fix-dev-shutdown

Conversation

@AmanVarshney01

@AmanVarshney01 AmanVarshney01 commented Aug 7, 2026

Copy link
Copy Markdown
Member

Summary

Port the shutdown fix onto the current DevSession lifecycle. This branch now includes current main and keeps the obsolete run-dev.ts implementation deleted.

  • Await every watcher close, including synchronous cleanup failures.
  • Stop scheduling rebuilds once shutdown begins and prevent a pending assembly from starting a late deployment.
  • Wait for active assembly/converge work before stopping local services.
  • Report cleanup failures without abandoning the remaining services or leaving the session unsettled.
  • Document the shutdown lifecycle in the local-dev guide and core-concepts skill.

Review fixes

Both existing review findings are addressed with focused regressions: synchronous/asynchronous service cleanup failures and shutdown during assembly/converge. No new signal listener, forced process-exit workaround, or dependency has been added.

Why the old release blocker no longer applies

The original draft planned to replace process-wide signal handling in run-dev.ts after an Alchemy/node-utils release. Current main has already removed that file and moved signal ownership into the consolidated CLI engine. This PR only fixes the remaining DevSession cleanup and rebuild races; it does not change or claim to fix the separate upstream signal-handler issue.

Verification

  • pnpm build: all 38 tasks passed.
  • @internal/cli typecheck passed.
  • Biome checks passed for all changed TypeScript files.
  • Full CLI suite: 264 passed, 3 platform-specific skips.
  • Existing CLI interrupt/session tests remain passing. Startup rollback covers successful cleanup and both synchronous/asynchronous cleanup failures.
  • Cross-platform CI and deploy checks will validate this exact head before merge.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Essentials

Run ID: a33c50f4-e044-4f42-a224-c229e0b2f69e

📥 Commits

Reviewing files that changed from the base of the PR and between 501ee24 and f5b0846.

📒 Files selected for processing (6)
  • docs/guides/running-locally.md
  • packages/0-framework/3-tooling/cli/src/dev/__tests__/watch.test.ts
  • packages/0-framework/3-tooling/cli/src/dev/watch.ts
  • packages/0-framework/3-tooling/cli/src/operations/__tests__/operations.test.ts
  • packages/0-framework/3-tooling/cli/src/operations/execute-dev.ts
  • skills/prisma-composer-core-concepts/SKILL.md

Included review availability: 2 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour.


Summary by CodeRabbit

  • Bug Fixes

    • Improved local development shutdown reliability by waiting for active rebuilds and watcher cleanup before stopping services.
    • Prevented new rebuilds, deploys, restarts, and post-shutdown events once shutdown begins.
    • Shutdown now continues remaining cleanup when individual cleanup steps fail, while reporting errors.
    • Made watcher shutdown safe to call repeatedly.
  • Documentation

    • Documented local development shutdown behavior, including cleanup sequencing and error reporting.

Walkthrough

The development CLI now returns an awaitable, idempotent watcher shutdown operation. It blocks new watcher-triggered rebuilds after shutdown starts, waits for active rebuilds, and continues service cleanup after reporting watcher or service-stop failures. Startup rollback follows the same cleanup sequence. Tests cover watcher failures, shutdown races, lifecycle events, and cleanup ordering. Local-development documentation describes the behavior.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to f5b08

Shutdown cleanup failures are contained before service teardown, so no merge-blocking risk was identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 4 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: waiting for active development rebuilds and watcher cleanup during shutdown.
Description check ✅ Passed The description is directly related to the changeset. It explains shutdown behavior, rebuild and watcher cleanup, error handling, documentation, regression tests, and verification results.
Full details: Docstring Coverage

Explanation

Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 4 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-dev-shutdown
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/fix-dev-shutdown

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@prisma/composer@206
npm i https://pkg.pr.new/@prisma/composer-cli@206
npm i https://pkg.pr.new/@prisma/composer-prisma-cloud@206

commit: 6606459

Wait for file watchers to close before reporting shutdown complete, and let a second signal force termination when graceful cleanup stalls.

Cover the shutdown controller with regression tests.

Signed-off-by: Aman Varshney <amanvarshney.work@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/0-framework/3-tooling/cli/src/dev/run-dev.ts`:
- Around line 303-314: Update the shutdown flow around
createDevShutdownController and the watch rebuild callback to track active
detached rebuild tasks, set a shutdown flag that prevents any pending or resumed
task from deploying, and await or cancel all tracked tasks before
attachment.stopServices completes and “[dev] stopped.” is logged.
- Around line 69-78: Update the cleanup handling in run-dev.ts around the
shutdown controller so cleanup is invoked via Promise.resolve().then(cleanup),
routing synchronous and asynchronous failures through the existing rejection
branch and ensuring done rejects. Add a regression test in
packages/0-framework/3-tooling/cli/src/dev/__tests__/run-dev.test.ts covering a
synchronously throwing cleanup and asserting shutdown.done rejects.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2a8a7fd0-0af2-4361-9f00-b66aa86d1911

📥 Commits

Reviewing files that changed from the base of the PR and between dae51eb and 501ee24.

📒 Files selected for processing (6)
  • docs/guides/running-locally.md
  • packages/0-framework/3-tooling/cli/src/dev/__tests__/run-dev.test.ts
  • packages/0-framework/3-tooling/cli/src/dev/__tests__/watch.test.ts
  • packages/0-framework/3-tooling/cli/src/dev/run-dev.ts
  • packages/0-framework/3-tooling/cli/src/dev/watch.ts
  • skills/prisma-composer/SKILL.md

Comment thread packages/0-framework/3-tooling/cli/src/dev/run-dev.ts Outdated
Comment thread packages/0-framework/3-tooling/cli/src/dev/run-dev.ts Outdated
@AmanVarshney01
AmanVarshney01 marked this pull request as draft August 7, 2026 11:43
@AmanVarshney01
AmanVarshney01 force-pushed the codex/fix-dev-shutdown branch from 501ee24 to 821d3c6 Compare August 7, 2026 11:43
Signed-off-by: Aman Varshney <amanvarshney.work@gmail.com>
@AmanVarshney01 AmanVarshney01 changed the title fix(cli): make dev shutdown reliable fix: wait for active dev rebuilds and watcher cleanup on shutdown Sep 14, 2026
@AmanVarshney01
AmanVarshney01 marked this pull request as ready for review September 14, 2026 19:12
@prisma-gizmo

prisma-gizmo Bot commented Sep 14, 2026

Copy link
Copy Markdown

✅ Gizmo reviewed 6606459 — posted 0 inline comment(s) this pass.

Open findings: none

Change walkthrough

Overview

This change fixes the dev session's shutdown behavior: it stops scheduling rebuilds once shutdown begins, drains in-flight assembly/converge work and watcher cleanup before stopping services, and surfaces synchronous as well as asynchronous cleanup failures without abandoning the remaining teardown.

How it fits the codebase

  • execute-dev.ts — The stopping flag is hoisted so the watch callback can ignore change events after shutdown starts, and every rebuild is tracked in a promise set that stop() awaits before touching services, closing the race where a late rebuild could redeploy after teardown. Rebuilds are abandoned at the next await boundary (after assembly or after converge), so a deployment that has already started is awaited rather than killed mid-flight, and no new ready event escapes after shutdown begins. The startup-failure path now wraps stopServices in Promise.resolve().then(...), so a synchronous throw during rollback no longer escapes the catch block and replaces the structured DEV.SERVICE_START_FAILED failure.
  • watch.tsWatchHandle.stop() returns a memoized promise built from Promise.allSettled over every chokidar close, rejecting with an AggregateError if any close fails; it is idempotent and trigger() becomes inert once stopped.
  • Event surfacestop-error is broadened from "one service refused to stop" to any watcher or service cleanup failure, with the CLI reporter message becoming the generic "Dev cleanup failed:" while keeping the existing warning step outcome. Doc comments no longer reference the deleted run-dev.ts.
  • Tests and docs — The rollback test is parametrized across success/sync-failure/async-failure cleanup, the stop-error test covers sync and async throws, and the shutdown-race test mocks startWatch to deterministically drive a rebuild blocked in either the assembly or converge phase, asserting services aren't stopped until in-flight work settles and a pre-deployment rebuild is skipped. The local-dev guide and core-concepts skill document the new shutdown ordering.

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New findings: 🟡 4 minor · trace

Findings outside the diff

  • 🟡 Minor · consistency packages/0-framework/3-tooling/cli/src/operations/dev.ts — dev.ts's stop-error event doc no longer matches when stop-error fires
    The PR adds a second emitter of stop-error: execute-dev.ts:326-329 now emits it when startedWatch.stop() rejects (watcher close failure), not just for services. The event's contract comment in the unchanged dev.ts:29 still reads "One service refused to stop during stop()", so a host consuming the typed events is told stop-error only ever means a service failure. Update the variant's doc to cover watcher-cleanup failures too.
    Recommended fix: Rewrite the comment on the stop-error variant in packages/0-framework/3-tooling/cli/src/operations/dev.ts to something like: "A service or the file watcher refused to stop cleanly during stop(); teardown continues and stopped still follows."
  • 🟡 Minor · consistency packages/0-framework/3-tooling/cli/src/operations/dev.ts — Doc comments still point to the deleted run-dev.ts for the signal-ownership pattern
    execute-dev.ts:5 and dev.ts:5 and dev.ts:43 still direct readers to run-dev.ts for the signal-handling pattern, but that file no longer exists (the PR description confirms signal ownership moved to the consolidated CLI engine). These are the canonical docs for the "host owns signals, never register handlers" invariant this PR's tests enforce; the dangling pointer sends readers to a 404. Not introduced by this PR, but it touches the same doc surface and its PR summary is about the run-dev.ts removal.
    Recommended fix: Replace the see run-dev.ts pointers with a reference to wherever signal ownership now lives (the consolidated CLI engine module), or drop the parenthetical.

Comment thread packages/0-framework/3-tooling/cli/src/dev/watch.ts Outdated
Signed-off-by: Aman Varshney <amanvarshney.work@gmail.com>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New findings: none · trace

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All Gizmo review threads are resolved and the head commit has been reviewed. Approving.

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