Skip to content

Commit 2a22b01

Browse files
committed
chore(webapp,core): remove v3 (engine V1) execution code
v3 (engine V1) is end-of-life. This removes the V1 execution stack while keeping every still-on-v3 request on a graceful 4xx path (never a 5xx): - the MarQS queue and its shared/dev queue consumers - the V1 socket.io namespaces (coordinator, provider, shared-queue) and the V1 attempt, checkpoint, and batch-resume lifecycle services - the graphile-worker / zod-worker background job stack - the DEPRECATE_V3_ENABLED flag (V1 is now rejected unconditionally) and the @trigger.dev/core v3/zodNamespace export Live queue reads (concurrency limits, env queue length, project metrics, admin queue debug) now read from the v2 run engine instead of MarQS. The batchTriggerV3 service and batch-completion worker stay live for current clients. A fresh dev environment now defaults to V2.
1 parent b9be9ff commit 2a22b01

77 files changed

Lines changed: 43 additions & 18058 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
Removed the unused `@trigger.dev/core/v3/zodNamespace` export, which was only used by the retired v3 engine.

.claude/rules/legacy-v3-code.md

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,24 @@ paths:
33
- "apps/webapp/app/v3/**"
44
---
55

6-
# Legacy V1 Engine Code in `app/v3/`
6+
# v3 (engine V1) has been removed
77

8-
The `v3/` directory name is misleading - most code here is actively used by the current V2 engine. Only the specific files below are legacy V1-only code.
8+
The v3 engine (RunEngineVersion `V1`: MarQS queue + Graphile worker) is end-of-life and its execution code has been removed from the webapp. The `app/v3/` directory name is historical: everything under it now serves the current V2 engine (`@internal/run-engine` + `@trigger.dev/redis-worker`).
99

10-
## V1-Only Files - Never Modify
10+
There is no `V1` execution path anymore. If you find a `RunEngineVersion` branch, the `V1` arm should only ever produce a graceful rejection, never run work. Do not reintroduce MarQS, the graphile worker, or the v3 socket.io namespaces.
1111

12-
- `marqs/` directory (entire MarQS queue system: sharedQueueConsumer, devQueueConsumer, fairDequeuingStrategy, devPubSub)
13-
- `legacyRunEngineWorker.server.ts` (V1 background job worker)
14-
- `services/triggerTaskV1.server.ts` (deprecated V1 task triggering)
15-
- `services/cancelTaskRunV1.server.ts` (deprecated V1 cancellation)
16-
- `authenticatedSocketConnection.server.ts` (V1 dev WebSocket using DevQueueConsumer)
17-
- `sharedSocketConnection.ts` (V1 shared queue socket using SharedQueueConsumer)
12+
## The deprecation boundary (keep this)
1813

19-
## V1/V2 Branching Pattern
14+
Requests from clients still on v3 (old SDK/CLI) or historical V1 runs must return a clean 4xx, never a 5xx. The boundary lives in:
2015

21-
Some services act as routers that branch on `RunEngineVersion`:
22-
- `services/cancelTaskRun.server.ts` - calls V1 service or `engine.cancelRun()` for V2
23-
- `services/batchTriggerV3.server.ts` - uses marqs for V1 path, run-engine for V2
16+
- `engineDeprecation.server.ts` - the `V3_TRIGGER_DEPRECATION_MESSAGE` / `V3_DEV_DEPRECATION_MESSAGE` / `V3_MIGRATION_URL` upgrade messages.
17+
- `engineVersion.server.ts` - `determineEngineVersion()` still detects a V1 project/run so callers can reject it.
18+
- `services/triggerTask.server.ts`, `services/cancelTaskRun.server.ts`, `services/rescheduleTaskRun.server.ts` - the `V1` arm rejects or finalizes gracefully instead of executing.
19+
- `services/initializeDeployment.server.ts` - the `DEPRECATE_V3_CLI_DEPLOYS_ENABLED`-gated v3 CLI deploy rejection.
20+
- `handleWebsockets.server.ts` - the legacy `trigger dev` websocket closes with the upgrade message.
2421

25-
When editing these shared services, only modify V2 code paths.
22+
## V2 modern stack
2623

27-
## V2 Modern Stack
28-
29-
- **Run lifecycle**: `@internal/run-engine` (internal-packages/run-engine)
30-
- **Background jobs**: `@trigger.dev/redis-worker` (not graphile-worker/zodworker)
31-
- **Queue operations**: RunQueue inside run-engine (not MarQS)
32-
- **V2 engine singleton**: `runEngine.server.ts`, `runEngineHandlers.server.ts`
33-
- **V2 workers**: `commonWorker.server.ts`, `alertsWorker.server.ts`, `batchTriggerWorker.server.ts`
24+
- **Run lifecycle**: `@internal/run-engine` (`runEngine.server.ts`, `runEngineHandlers.server.ts`)
25+
- **Background jobs**: `@trigger.dev/redis-worker` (`commonWorker.server.ts`, `alertsWorker.server.ts`, `batchTriggerWorker.server.ts`; `legacyRunEngineWorker.server.ts` still hosts the live batch-completion jobs)
26+
- **Queue operations**: RunQueue inside run-engine (`runQueue.server.ts`), not MarQS
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: breaking
4+
---
5+
6+
Removed support for the end-of-life v3 engine. Instances or projects still on v3 must stay on the 4.5.x release line or upgrade to v4; v3 triggers, batch triggers, reschedules, and deploys now return a clear upgrade message instead of running.

apps/webapp/app/components/admin/debugRun.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ function DebugRunDataEngineV2({
104104
envConcurrencyLimit,
105105
envCurrentConcurrency,
106106
keys,
107-
}: UseDataFunctionReturn<typeof loader>) {
107+
}: Extract<UseDataFunctionReturn<typeof loader>, { engine: "V2" }>) {
108108
return (
109109
<Property.Table>
110110
<Property.Item>

apps/webapp/app/entry.server.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { parseAcceptLanguage } from "intl-parse-accept-language";
77
import isbot from "isbot";
88
import { renderToPipeableStream } from "react-dom/server";
99
import { PassThrough } from "stream";
10-
import * as Worker from "~/services/worker.server";
1110
import { initMollifierDrainerWorker } from "~/v3/mollifierDrainerWorker.server";
1211
import { initMollifierStaleSweepWorker } from "~/v3/mollifierStaleSweepWorker.server";
1312
import { initBillingLimitWorker } from "~/v3/billingLimitWorker.server";
@@ -227,10 +226,6 @@ export const handleError = wrapHandleErrorWithSentry((error, { request }) => {
227226
}
228227
});
229228

230-
Worker.init().catch((error) => {
231-
logError(error);
232-
});
233-
234229
initMollifierDrainerWorker();
235230
initMollifierStaleSweepWorker();
236231
initBillingLimitWorker();
@@ -241,10 +236,6 @@ bootstrap().catch((error) => {
241236

242237
function logError(error: unknown, request?: Request) {
243238
console.error(error);
244-
245-
if (error instanceof Error && error.message.startsWith("There are locked jobs present")) {
246-
console.log("⚠️ graphile-worker migration issue detected!");
247-
}
248239
}
249240

250241
process.on("uncaughtException", (error, origin) => {

apps/webapp/app/env.server.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,6 @@ const EnvironmentSchema = z
224224
PLAIN_CUSTOMER_CARDS_SECRET: z.string().optional(),
225225
PLAIN_CUSTOMER_CARDS_KEY: z.string().optional(),
226226
PLAIN_CUSTOMER_CARDS_HEADERS: z.string().optional(),
227-
WORKER_SCHEMA: z.string().default("graphile_worker"),
228-
WORKER_CONCURRENCY: z.coerce.number().int().default(10),
229-
WORKER_POLL_INTERVAL: z.coerce.number().int().default(1000),
230227
// How often each replica reloads the global flags snapshot from the DB.
231228
// Sets kill/ramp propagation latency.
232229
GLOBAL_FLAGS_RELOAD_INTERVAL_MS: z.coerce.number().int().min(1000).default(5000),
@@ -528,9 +525,6 @@ const EnvironmentSchema = z
528525
API_RATE_LIMIT_JWT_WINDOW: z.string().default("1m"),
529526
API_RATE_LIMIT_JWT_TOKENS: z.coerce.number().int().default(60),
530527

531-
//v3
532-
PROVIDER_SECRET: z.string().default("provider-secret"),
533-
COORDINATOR_SECRET: z.string().default("coordinator-secret"),
534528
DEPOT_TOKEN: z.string().optional(),
535529
DEPOT_ORG_ID: z.string().optional(),
536530
DEPOT_REGION: z.string().default("us-east-1"),
@@ -618,15 +612,6 @@ const EnvironmentSchema = z
618612
// log-only mode before enforcement.
619613
DEPRECATE_V3_CLI_DEPLOYS_ENABLED: z.string().default("0"),
620614

621-
// Master switch for the v3 engine (RunEngineVersion.V1) shutdown. When
622-
// enabled it: rejects triggers that resolve to V1 (single, batch, schedule,
623-
// replay, triggerAndWait) with a graceful error pointing at the v4 migration
624-
// guide; closes the legacy `trigger dev` websocket used by v3 CLIs; and turns
625-
// the V1 run-lifecycle background jobs (heartbeat timeout, TTL expiry, retry,
626-
// resume, scheduled fires) into no-ops so abandoned V1 runs stop generating
627-
// database load. v4 (V2) is never affected (every gate also checks the run is
628-
// V1). Defaults to off so self-hosted instances still on V1 keep working.
629-
DEPRECATE_V3_ENABLED: z.string().default("0"),
630615

631616
// Verify the deploy image exists before promoting. Disable for out-of-band/air-gapped push. ECR only.
632617
DEPLOY_IMAGE_VERIFICATION_ENABLED: BoolEnv.default(true),
@@ -815,7 +800,6 @@ const EnvironmentSchema = z
815800

816801
PROD_TASK_HEARTBEAT_INTERVAL_MS: z.coerce.number().int().optional(),
817802

818-
VERBOSE_GRAPHILE_LOGGING: z.string().default("false"),
819803
V2_MARQS_ENABLED: z.string().default("0"),
820804
V2_MARQS_CONSUMER_POOL_ENABLED: z.string().default("0"),
821805
V2_MARQS_CONSUMER_POOL_SIZE: z.coerce.number().int().default(10),

apps/webapp/app/routes/admin.concurrency.tsx

Lines changed: 0 additions & 39 deletions
This file was deleted.

apps/webapp/app/routes/api.v1.runs.$runParam.attempts.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

apps/webapp/app/routes/resources.batches.$batchId.check-completion.ts

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { parseWithZod } from "@conform-to/zod";
22
import type { ActionFunction } from "@remix-run/node";
33
import { json } from "@remix-run/node";
4-
import { assertExhaustive } from "@trigger.dev/core/utils";
54
import { z } from "zod";
65
import { prisma } from "~/db.server";
76
import { redirectWithErrorMessage, redirectWithSuccessMessage } from "~/models/message.server";
@@ -10,7 +9,7 @@ import { requireUserId } from "~/services/session.server";
109
import { sanitizeRedirectPath } from "~/utils";
1110
import { runStore } from "~/v3/runStore.server";
1211
import { findBatchRunIdForUser } from "~/v3/services/batchRunAccess.server";
13-
import { ResumeBatchRunService } from "~/v3/services/resumeBatchRun.server";
12+
import { tryCompleteBatchV3 } from "~/v3/services/batchTriggerV3.server";
1413

1514
export const checkCompletionSchema = z.object({
1615
redirectUrl: z.string(),
@@ -44,35 +43,10 @@ export const action: ActionFunction = async ({ request, params }) => {
4443
}
4544

4645
try {
47-
const resumeBatchRunService = new ResumeBatchRunService();
48-
// Resume by the resolved internal id: the service looks up strictly by
49-
// `{ id }`, so passing a friendlyId param would resolve to nothing.
50-
const resumeResult = await resumeBatchRunService.call(ownedBatchRunId);
46+
// v3 (engine V1) is retired; finalize the batch through the v2 completion path (no-op if not ready).
47+
await tryCompleteBatchV3(ownedBatchRunId, prisma, true);
5148

52-
let message: string | undefined;
53-
54-
switch (resumeResult) {
55-
case "ERROR": {
56-
throw "Unknown error during batch completion check";
57-
}
58-
case "ALREADY_COMPLETED": {
59-
message = "Batch already completed.";
60-
break;
61-
}
62-
case "COMPLETED": {
63-
message = "Batch completed and parent tasks resumed.";
64-
break;
65-
}
66-
case "PENDING": {
67-
message = "Child runs still in progress. Please try again later.";
68-
break;
69-
}
70-
default: {
71-
assertExhaustive(resumeResult);
72-
}
73-
}
74-
75-
return redirectWithSuccessMessage(safeRedirectUrl, request, message);
49+
return redirectWithSuccessMessage(safeRedirectUrl, request, "Batch completion checked.");
7650
} catch (error) {
7751
if (error instanceof Error) {
7852
logger.error("Failed to check batch completion", {

apps/webapp/app/routes/resources.taskruns.$runParam.debug.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
118118
];
119119

120120
return typedjson({
121-
engine: "V2",
121+
engine: "V2" as const,
122122
run,
123123
environment,
124124
queueConcurrencyLimit,

0 commit comments

Comments
 (0)