Skip to content

Load QuickJS lazily and cap concurrent session builds - #1840

Merged
RhysSullivan merged 3 commits into
mainfrom
lazy-quickjs-init
Aug 29, 2026
Merged

Load QuickJS lazily and cap concurrent session builds#1840
RhysSullivan merged 3 commits into
mainfrom
lazy-quickjs-init

Conversation

@RhysSullivan

@RhysSullivan RhysSullivan commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Cold MCP session starts on Cloudflare currently pay the full QuickJS-WASM instantiation cost (~1.4s CPU) during init, even though QuickJS is only used for artifact smoke-rendering. This PR moves that load to the first artifact create/edit call instead, memoized per isolate, so a plain MCP session never pays for it.

It also adds a small per-isolate semaphore capping concurrent cold buildMcpServer builds to 4, with FIFO queuing, so a burst of new sessions landing on one isolate no longer runs every build at once. Queued wait time is recorded on the init span when nonzero.

Admission control is interruption-safe and bounded:

  • If a session's build is interrupted while queued (e.g. a client disconnect during a burst), its slot reservation is cancelled cleanly instead of being granted later to a fiber that is no longer listening — this closes a slot leak that would otherwise deadlock later builds on the isolate.
  • A queued build that waits more than 10s for a slot proceeds without one rather than stalling indefinitely, so a stuck/slow build (e.g. a hung dependency during an incident) degrades back to old unbounded-concurrent behavior instead of blocking everything queued behind it. This is flagged on the init span (mcp.init.build_queue_timeout).

Verified with bun run typecheck, bun run lint, and bun run format:check (all clean on the changed files), the session-build-semaphore.test.ts unit tests (cap, FIFO order, release-on-failure, cancel-while-queued, cancel-after-grant, queue timeout), and the artifacts.test.ts and mcp-execute.test.ts e2e scenarios against the cloud target, which cover artifact create/edit through the smoke-render path and a basic session build.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 29, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 8a08453 Commit Preview URL

Branch Preview URL
Aug 29 2026, 07:15 AM

@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 29, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud 8a08453 Aug 29 2026, 07:15 AM

@pkg-pr-new

pkg-pr-new Bot commented Aug 29, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1840

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1840

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1840

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1840

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1840

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1840

executor

npm i https://pkg.pr.new/executor@1840

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1840

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1840

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1840

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1840

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1840

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1840

commit: 8a08453

A queued waiter interrupted mid-wait (client disconnect during a burst)
used to leave its slot permanently unowned: the underlying promise
couldn't be cancelled, so a later release would still hand it the slot
with no fiber left to free it. acquireBuildSlot now returns a handle
with an idempotent cancel() that dequeues an unstarted waiter or hands
back an already-granted slot, wired through Effect.promise's abort
signal plus an ensuring finalizer that both call the same cancel().

Also add a 10s max queue wait: a waiter that isn't granted a slot in
time proceeds without one and is flagged on the span, so a stalled
build degrades queued admission back to old unbounded-concurrent
behavior instead of stalling everything behind it forever.
@RhysSullivan
RhysSullivan marked this pull request as ready for review August 29, 2026 18:32
@RhysSullivan
RhysSullivan merged commit 1d483a8 into main Aug 29, 2026
44 checks passed
@RhysSullivan
RhysSullivan deleted the lazy-quickjs-init branch August 29, 2026 18:32
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