Skip to content

feat(cache): deploy probed manifests in two stages - #3093

Open
james-elicx wants to merge 15 commits into
codex/cacheability-use-cache-ownershipfrom
codex/cacheability-two-stage-deploy
Open

feat(cache): deploy probed manifests in two stages#3093
james-elicx wants to merge 15 commits into
codex/cacheability-use-cache-ownershipfrom
codex/cacheability-two-stage-deploy

Conversation

@james-elicx

@james-elicx james-elicx commented Aug 26, 2026

Copy link
Copy Markdown
Member

Capability stack 6/9. Exact head: 03d5e5edf7fa831c68e110ec96a00c1af21f12e6. Base: #3103.

Full chain: #3108#3090#3091#3092#3103#3093#3094#3098#3113.

Summary

Implement the two-upload deployment protocol:

  1. upload the built Worker with its inert cacheability module
  2. stage that probe version at 0%
  3. discover concrete requests against that exact staged version
  4. probe exact HTML, full-RSC, and loading-shell identities
  5. abort if classification or deployment-state validation fails
  6. omit dynamic identities and deterministically bound the static-only manifest
  7. verify the generated Wrangler main reaches the manifest module
  8. upload the isolated manifest-bearing artifact
  9. stage, warm, and promote only static identities

A valid empty manifest is also deployed: zero-discovered and all-dynamic applications upload the final fail-closed Worker, skip warming, and either promote it or leave it staged when --warm-cdn-no-promote is set.

The normal flow makes one final cache-fill request per admitted identity. It does not perform certification or a second fill request; #3094 adds that only behind --warm-cdn-certify.

Deployment-state safety

  • long-running probe/upload/warm windows compare both Wrangler's deployment ID and the exact version percentages
  • deployment state is checked after probe staging, before and after the final upload, after final staging, and before promotion
  • if wrangler versions deploy throws after Cloudflare created the deployment but failed while synchronizing settings, the CLI immediately re-reads state and reports whether the requested stage/promotion happened, the prior state remains, or the outcome is unknown
  • successful --warm-cdn-no-promote and post-stage failures apply production triggers exactly once; the help text explicitly states that no-promote leaves those triggers applied while the old version remains at 100%

Remaining concurrency boundary

Cloudflare's create-deployment API and Wrangler expose no ETag, If-Match, expected deployment ID, or other compare-and-swap precondition. Deployment-ID checks close observable long windows, but cannot make the final status-read → deployment-POST pair atomic. Deploy pipelines for the same Worker must therefore be serialized; a separate writer racing inside that final API-call window can still overwrite state, as it can with ordinary wrangler versions deploy.

Artifact model

The manifest is an ESM module included in the second Worker upload. It is not an environment, service, KV, or static-assets binding. The original build directory is not mutated; an isolated copy replaces only __vinext_cacheability_manifest.js.

Application code is not rebuilt between uploads. Dynamic identities are represented by absence and are neither embedded nor rendered again during final warming.

Review guide

  1. packages/cloudflare/src/cacheability-probe.ts sends authenticated version-pinned probes, cancels stale bodies, and emits a deterministic static-only result.
  2. packages/cloudflare/src/cacheability-artifact.ts validates module reachability and enforces route/byte bounds.
  3. packages/cloudflare/src/deploy.ts owns probe upload → final upload → static-only warm → promotion, deployment identity checks, and post-command reconciliation.
  4. packages/cloudflare/src/version-deploy.ts parses Wrangler's deployment ID and traffic state.
  5. tests/cloudflare-cdn-warm-deploy.test.ts proves mixed filtering, fail-closed orchestration, no-promote behavior, concurrent-state rejection, and all reconciled failure outcomes.

Review size

Layer-only diff against this PR's base: 28 files, +2,888/-119.

Validation

  • exact-layer CDN deploy orchestration — 57/57 before the final Route Handler extension
  • valid zero-discovered, all-dynamic, and --warm-cdn-no-promote empty-manifest flows are covered
  • current full-stack cumulative changed-file suites — 2,864/2,864
  • current full-stack PPR probe/admission/Pages built-workerd E2E — 8/8
  • current full-stack vp check and git diff --check
  • layer exact-head CI and deploy previews are green
@pkg-pr-new

pkg-pr-new Bot commented Aug 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@vinext/cloudflare@3093
npm i https://pkg.pr.new/create-vinext-app@3093
npm i https://pkg.pr.new/@vinext/types@3093
npm i https://pkg.pr.new/vinext@3093

commit: 03d5e5e

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Performance benchmarks

Compared 03d5e5e against base e2f0558 using alternating same-runner rounds. Next.js was unchanged and skipped.

0 improved · 0 regressed · 6 within ±1.5%

Scenario Framework Baseline Current Change
Client bundle size (gzip) vinext 142.2 KB 142.3 KB ⚫ +0.0%
Client entry size (gzip) vinext 129.5 KB 129.6 KB ⚫ +0.0%
Dev server cold start vinext 2.52 s 2.52 s ⚫ +0.1%
Production build time vinext 2.69 s 2.71 s ⚫ +0.6%
RSC entry closure size (gzip) vinext 119.0 KB 118.9 KB ⚫ -0.0%
Server bundle size (gzip) vinext 202.3 KB 202.3 KB ⚫ -0.0%

View detailed results and traces

🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
Example Preview Production Original
app-router-cloudflare preview production
pages-router-cloudflare preview production
app-router-playground preview production original
realworld-api-rest preview production
nextra-docs-template preview production
benchmarks preview production
hackernews preview production original
workers-cache preview production
static-export preview production
web preview production
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 5f0f93a to 86bfd1d Compare August 26, 2026 14:45
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 86bfd1d to d8edfb7 Compare August 26, 2026 17:14
@james-elicx james-elicx reopened this Aug 26, 2026
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from d8edfb7 to 88ecf0f Compare August 26, 2026 17:18
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 88ecf0f to a015349 Compare August 26, 2026 18:01
@james-elicx
james-elicx changed the base branch from codex/cacheability-manifest-admission to codex/cacheability-use-cache-ownership August 26, 2026 18:05
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from a015349 to 5b19e9d Compare August 26, 2026 18:29
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 5b19e9d to 3b67854 Compare August 26, 2026 19:33
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 3b67854 to b94677e Compare August 26, 2026 19:42
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from b94677e to 3ac792c Compare August 26, 2026 22:22
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 3ac792c to e1f432b Compare August 26, 2026 22:31
@james-elicx

Copy link
Copy Markdown
Member Author

/bigbonk review for issues. Hard time limit: 20 minutes; return all findings or a partial review by then.

@ask-bonk

ask-bonk Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

@james-elicx Bonk workflow was cancelled.

View workflow run · To retry, trigger Bonk again.

@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 26f6ed1 to 3ad2c96 Compare August 27, 2026 00:43
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 3ad2c96 to aba8b6f Compare August 27, 2026 00:58
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch 2 times, most recently from 47d046b to 68e846a Compare August 27, 2026 01:24
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 68e846a to 6668f7c Compare August 27, 2026 01:41
@james-elicx
james-elicx force-pushed the codex/cacheability-two-stage-deploy branch from 6668f7c to 03d5e5e Compare August 27, 2026 01:50
@james-elicx
james-elicx marked this pull request as ready for review August 27, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant