Skip to content

[wrangler] serialize custom build watch events to avoid concurrent runs#12704

Open
dhruv7539 wants to merge 3 commits intocloudflare:mainfrom
dhruv7539:codex/serialize-custom-build-watch-events-10944
Open

[wrangler] serialize custom build watch events to avoid concurrent runs#12704
dhruv7539 wants to merge 3 commits intocloudflare:mainfrom
dhruv7539:codex/serialize-custom-build-watch-events-10944

Conversation

@dhruv7539
Copy link
Copy Markdown

@dhruv7539 dhruv7539 commented Feb 27, 2026

Summary

  • serialize custom build watch-triggered runs in BundlerController
  • keep only the latest pending file-change build request when many events arrive in a burst
  • preserve stale-build suppression by retaining the existing abort-controller checks

Why

Fixes the behavior in #10944 where rapid multi-file changes can start multiple custom builds at once.

Testing

  • pnpm -C packages/wrangler test src/__tests__/api/startDevWorker/BundleController.test.ts
  • pnpm -C packages/wrangler exec eslint src/api/startDevWorker/BundlerController.ts src/__tests__/api/startDevWorker/BundleController.test.ts

Added regression test

  • custom build watcher changes are processed without concurrent custom builds
  • uses a lock file in a test custom-build script to fail if two builds overlap
  • updates multiple watched files in quick succession and verifies no Custom build failed events are emitted

Open with Devin

@dhruv7539 dhruv7539 requested a review from a team as a code owner February 27, 2026 18:45
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 27, 2026

🦋 Changeset detected

Latest commit: 9e7dab9

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

devin-ai-integration[bot]

This comment was marked as resolved.

@dhruv7539
Copy link
Copy Markdown
Author

Addressed both actionable comments in the latest push (8ae0df1):\n- fixed wiring in custom-build path to use \n- added a Wrangler patch changeset ()

@dhruv7539
Copy link
Copy Markdown
Author

Addressed both actionable comments in the latest push (8ae0df1ef):

  • fixed jsxFragment wiring in BundlerController custom-build path to use config.build.jsxFragment
  • added a Wrangler patch changeset (.changeset/quick-keys-smell.md)

@petebacondarwin petebacondarwin force-pushed the codex/serialize-custom-build-watch-events-10944 branch from 8ae0df1 to 90cb61d Compare April 15, 2026 06:28
@workers-devprod
Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • packages/wrangler/src/tests/api/startDevWorker/BundleController.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/BundlerController.ts: [@cloudflare/wrangler]

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 7 additional findings in Devin Review.

Open in Devin Review

);
});

test("custom build watcher changes are processed without concurrent custom builds", async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 New test uses global expect instead of test context ({ expect }), violating AGENTS.md rule

The new test at line 258 uses async () => { without destructuring expect from the test context, then calls expect(customBuildErrors).toHaveLength(0) at line 313 using the global expect. This violates the explicit rule in packages/wrangler/AGENTS.md: "Never import expect from vitest — use test context ({ expect }) => {}". Every other test in this file (lines 72, 132, 185, 318, 371, 493, 603, 644) correctly uses the async ({ expect }) => { pattern.

Suggested change
test("custom build watcher changes are processed without concurrent custom builds", async () => {
test("custom build watcher changes are processed without concurrent custom builds", async ({ expect }) => {
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@petebacondarwin petebacondarwin requested review from a team and vicb and removed request for a team April 15, 2026 06:53
@petebacondarwin petebacondarwin force-pushed the codex/serialize-custom-build-watch-events-10944 branch from 90cb61d to c5495bd Compare April 15, 2026 08:18
@github-project-automation github-project-automation bot moved this to Untriaged in workers-sdk Apr 15, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 15, 2026

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@12704

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@12704

miniflare

npm i https://pkg.pr.new/miniflare@12704

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@12704

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@12704

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@12704

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@12704

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@12704

wrangler

npm i https://pkg.pr.new/wrangler@12704

commit: c5495bd

@workers-devprod
Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • packages/wrangler/src/tests/api/startDevWorker/BundleController.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/BundlerController.ts: [@cloudflare/wrangler]

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 10 additional findings in Devin Review.

Open in Devin Review

Comment on lines +67 to +74
while (this.#pendingCustomBuild) {
const nextBuild = this.#pendingCustomBuild;
this.#pendingCustomBuild = undefined;
await this.#runCustomBuild(
nextBuild.config,
nextBuild.filePath,
nextBuild.buildAborter
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Stale pending custom build executes its external command when aborter is already aborted

When a config update (#startCustomBuild) occurs while a custom build is pending in the queue, #startCustomBuild at BundlerController.ts:230 aborts this.#customBuildAborter (which is the same AbortController stored in #pendingCustomBuild.buildAborter). However, #runPendingCustomBuilds at line 67-74 does not check buildAborter.signal.aborted before dequeuing and running the stale pending build, and #runCustomBuild at line 88-89 emits a bundleStart event and executes the external build command before checking the abort signal at line 101. This means a build known to be cancelled still runs its external command, emits a spurious bundleStart (without a matching bundleComplete), and if the external command fails, emits a confusing error event to downstream consumers (ProxyController, RuntimeControllers per DevEnv.ts:101-104). Adding an early abort guard would avoid this unnecessary work.

Suggested change
while (this.#pendingCustomBuild) {
const nextBuild = this.#pendingCustomBuild;
this.#pendingCustomBuild = undefined;
await this.#runCustomBuild(
nextBuild.config,
nextBuild.filePath,
nextBuild.buildAborter
);
while (this.#pendingCustomBuild) {
const nextBuild = this.#pendingCustomBuild;
this.#pendingCustomBuild = undefined;
if (nextBuild.buildAborter.signal.aborted) {
continue;
}
await this.#runCustomBuild(
nextBuild.config,
nextBuild.filePath,
nextBuild.buildAborter
);
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

3 participants