chore(webapp,core): remove the end-of-life v3 (engine V1) execution stack (#4236)
## Summary v3 (the engine that ran the SDK v3 era, internally `RunEngineVersion.V1`) is end-of-life. Following the removal of the v3 execution apps ([#4194](https://github.com/triggerdotdev/trigger.dev/pull/4194)) and the legacy dev websocket ([#4198](https://github.com/triggerdotdev/trigger.dev/pull/4198)), this removes the remaining v3 execution stack from the server. Clients still on v3 (an old SDK or CLI that has not upgraded) keep getting a clear "upgrade to v4" response. Triggers, batch triggers, reschedules, and deploys that resolve to v3 are rejected with a graceful 4xx pointing at the migration guide, never a 5xx, so a stale client cannot affect server health. Self-hosted instances still running v3 should stay on the 4.5.x release line until they migrate. ## What is removed - The MarQS queue and its shared/dev queue consumers. - The v3 socket.io namespaces (coordinator, provider, shared-queue) and the v3 run lifecycle services (attempt, checkpoint, and batch-resume). - The graphile-worker background job system; all live jobs already run on `@trigger.dev/redis-worker`. - The `DEPRECATE_V3_ENABLED` flag: v3 is now rejected unconditionally, so the flag is gone. - Unused v3 exports from `@trigger.dev/core` (the `v3/zodNamespace` subpath and the legacy socket message catalogs) and the now-dead MarQS environment variables. ## What stays The v4 engine is untouched. The graceful v3 rejection boundary stays, `determineEngineVersion` still detects a v3 project so it can reject it, and the batch service plus batch-completion worker stay for current clients. Live queue concurrency limits and metrics now read from the v4 run engine instead of MarQS, and a brand-new dev environment now defaults to v4. ## Dependency cleanup Removes webapp dependencies left unused by this change: `seedrandom` and `semver` (only the removed v3 code used them) plus a set that was already dead, their orphaned `@types` packages, and two dead files. Adds a `knip:deps` script and a `knip.json` config so unused dependencies can be found the same way going forward.
This commit is contained in:
@@ -1,146 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const filename = process.argv[2];
|
||||
|
||||
if (!filename) {
|
||||
console.error("Usage: analyze_marqs.mjs <filename>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
import fs from "fs/promises";
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const input = await fs.readFile(filename, "utf-8");
|
||||
|
||||
await processInput(input);
|
||||
} catch (err) {
|
||||
console.error(`Error reading file: ${err}`);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
|
||||
// input is jsonl format, we want to split by line and then JSON parse each line
|
||||
async function processInput(input) {
|
||||
const rows = [];
|
||||
const lines = input.split("\n");
|
||||
for (const line of lines) {
|
||||
if (!line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const row = JSON.parse(line);
|
||||
|
||||
// process each row
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
const queueChoiceCounts = {};
|
||||
const queueMaxAges = {};
|
||||
const queueMaxSizes = {};
|
||||
const nextRangeOffsetCounts = {};
|
||||
const consumerStats = {};
|
||||
const rowsByConsumer = {};
|
||||
|
||||
console.log(`Processed ${rows.length} rows`);
|
||||
|
||||
// console.log(util.inspect(rows[0], { depth: 20 }));
|
||||
|
||||
for (const row of rows) {
|
||||
const queueChoice = row.queueChoice;
|
||||
|
||||
if (queueChoice) {
|
||||
if (!queueChoiceCounts[queueChoice]) {
|
||||
queueChoiceCounts[queueChoice] = 0;
|
||||
}
|
||||
queueChoiceCounts[queueChoice]++;
|
||||
}
|
||||
}
|
||||
|
||||
for (const row of rows) {
|
||||
rowsByConsumer[row.consumerId] = rowsByConsumer[row.consumerId] || [];
|
||||
rowsByConsumer[row.consumerId].push(row);
|
||||
|
||||
const queueChoice = row.queueChoice;
|
||||
|
||||
if (!consumerStats[row.consumerId]) {
|
||||
consumerStats[row.consumerId] = {
|
||||
queueChoiceCounts: {},
|
||||
totalQueueChoices: 0,
|
||||
noQueueChoiceCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (queueChoice) {
|
||||
const queueData = row.queuesWithScores.find((queue) => queue.queue === queueChoice);
|
||||
|
||||
console.log(
|
||||
`[${row.timestamp}] -> ${queueChoice} [age:${queueData.age}] [size:${queueData.size}] [nextRange.offset=${row.nextRange.offset}] [queuesWithScores=${row.queuesWithScores.length}] [${row.consumerId}]`
|
||||
);
|
||||
|
||||
if (!queueMaxAges[queueChoice] || queueData.age > queueMaxAges[queueChoice]) {
|
||||
queueMaxAges[queueChoice] = queueData.age;
|
||||
}
|
||||
|
||||
if (!queueMaxSizes[queueChoice] || queueData.size > queueMaxSizes[queueChoice]) {
|
||||
queueMaxSizes[queueChoice] = queueData.size;
|
||||
}
|
||||
|
||||
if (!consumerStats[row.consumerId].queueChoiceCounts[queueChoice]) {
|
||||
consumerStats[row.consumerId].queueChoiceCounts[queueChoice] = 0;
|
||||
}
|
||||
|
||||
consumerStats[row.consumerId].queueChoiceCounts[queueChoice]++;
|
||||
consumerStats[row.consumerId].totalQueueChoices++;
|
||||
} else {
|
||||
console.log(
|
||||
`[${row.timestamp}] -> No queue choice [nextRange.offset=${row.nextRange.offset}] [queuesWithScores=${row.queuesWithScores.length}] [${row.consumerId}]`
|
||||
);
|
||||
|
||||
consumerStats[row.consumerId].noQueueChoiceCount++;
|
||||
}
|
||||
|
||||
if (!nextRangeOffsetCounts[row.nextRange.offset]) {
|
||||
nextRangeOffsetCounts[row.nextRange.offset] = 0;
|
||||
}
|
||||
|
||||
nextRangeOffsetCounts[row.nextRange.offset]++;
|
||||
}
|
||||
|
||||
console.log("Queue choice counts:");
|
||||
console.log(queueChoiceCounts);
|
||||
|
||||
console.log("Queue max ages:");
|
||||
console.log(queueMaxAges);
|
||||
|
||||
console.log("Queue max sizes:");
|
||||
console.log(queueMaxSizes);
|
||||
|
||||
console.log("Next range offset counts:");
|
||||
console.log(nextRangeOffsetCounts);
|
||||
|
||||
for (const consumerId in consumerStats) {
|
||||
console.log(`Consumer ${consumerId}:`);
|
||||
console.log(consumerStats[consumerId]);
|
||||
}
|
||||
|
||||
for (const consumerId in rowsByConsumer) {
|
||||
console.log(`\n## Consumer ${consumerId}:`);
|
||||
|
||||
for (const row of rowsByConsumer[consumerId]) {
|
||||
const queueChoice = row.queueChoice;
|
||||
|
||||
if (queueChoice) {
|
||||
const queueData = row.queuesWithScores.find((queue) => queue.queue === queueChoice);
|
||||
|
||||
console.log(
|
||||
`[${row.timestamp}] -> ${queueChoice} [age:${queueData.age}] [size:${queueData.size}] [nextRange.offset=${row.nextRange.offset}] [queuesWithScores=${row.queuesWithScores.length}] [${row.consumerId}]`
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`[${row.timestamp}] -> No queue choice [nextRange.offset=${row.nextRange.offset}] [queuesWithScores=${row.queuesWithScores.length}] [${row.consumerId}]`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user