Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/cloud/src/edge/production-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ const shipped: V2EdgeEnv = {
};

describe("production v2 edge settings", () => {
it("binds V2 to exactly one Worker", () => {
it("binds V2 to the unplaced marketing gateway", () => {
const bindings = config.services.filter((service) => service.binding === "V2");
expect(bindings).toHaveLength(1);
expect(bindings[0]?.service).toMatch(/^[a-z0-9-]+$/);
expect(bindings[0]?.service).toBe("executor-next-marketing-v2");
});

it("redirects sign-up to v2's sign-up page on app.executor.sh", async () => {
Expand Down
17 changes: 7 additions & 10 deletions apps/cloud/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,6 @@ const cloudflareHandler = {
fetch: async (request, env, ctx) => {
isolateRequestSeq += 1;

// Public pages must not enter TanStack Start: its first-request dynamic
// import loads the entire React + Effect server graph and can take seconds
// on a cold isolate. Classify and service-bind marketing at the Worker
// entry, before telemetry or fetchHandler touches that graph.
// Everything that returns before the app-plane dispatch below leaves the
// graph unevaluated for the next request; warm it in the background.
if (!servedByAppPlane(new URL(request.url).pathname, request.method)) {
prewarmAppPlane(ctx);
}

// On `executor.sh`, v2 answers marketing (including `/docs` and its
// telemetry proxies), sign-up, the fixed list of v2 paths and v2's
// connected-account callbacks; v1's legal pages stay on v1's marketing
Expand All @@ -329,6 +319,13 @@ const cloudflareHandler = {
const marketing: Fetcher | undefined = env.MARKETING;
if (marketingRequest && marketing) return marketing.fetch(marketingRequest);

// Only v1-owned requests may warm v1's application. A dynamic import still
// evaluates JavaScript on this isolate's thread under waitUntil; starting it
// for a forwarded page or stylesheet delays the otherwise independent response.
if (!servedByAppPlane(new URL(request.url).pathname, request.method)) {
prewarmAppPlane(ctx);
}

// Same reasoning, same seam: `/docs` and the PostHog proxy forward to an
// external origin and never touch the router, React, or the Effect app.
// Left in Start's middleware they still paid its lazy `loadEntries` import
Expand Down
4 changes: 2 additions & 2 deletions apps/cloud/wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@
"binding": "MARKETING",
"service": "executor-marketing",
},
// v2's API Worker (the executor-next `v2` stage, same account). The edge
// v2's unplaced marketing Worker (the executor-next `v2` stage, same account). The edge
// (src/edge/marketing.ts) forwards marketing and a fixed list of
// executor.sh paths to it with the URL unchanged, so v2 sees host
// `executor.sh`.
{
"binding": "V2",
// v2's Worker name. It must equal the name v2's deployment pins for
// this binding; this is the only place v1 names it.
"service": "executor-next-hosted-api-v2-qs32brgjwvt7ytx4",
"service": "executor-next-marketing-v2",
},
],
"hyperdrive": [
Expand Down
Loading