chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
import { ownerEngine } from "@trigger.dev/core/v3/isomorphic";
|
||||
import { env } from "~/env.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
import { marqs } from "~/v3/marqs/index.server";
|
||||
import { commonWorker } from "../commonWorker.server";
|
||||
import { BaseService } from "./baseService.server";
|
||||
|
||||
export class ExecuteTasksWaitingForDeployService extends BaseService {
|
||||
public async call(backgroundWorkerId: string) {
|
||||
// Kill-switch for the legacy V1 WAITING_FOR_DEPLOY drain. Set to "1" to
|
||||
// neuter any jobs already enqueued (V2 has its own PENDING_VERSION path).
|
||||
if (env.LEGACY_RUN_ENGINE_WAITING_FOR_DEPLOY_DISABLED === "1") {
|
||||
return;
|
||||
}
|
||||
|
||||
const backgroundWorker = await this._prisma.backgroundWorker.findFirst({
|
||||
where: {
|
||||
id: backgroundWorkerId,
|
||||
},
|
||||
include: {
|
||||
runtimeEnvironment: {
|
||||
include: {
|
||||
project: true,
|
||||
organization: true,
|
||||
},
|
||||
},
|
||||
tasks: {
|
||||
select: {
|
||||
slug: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!backgroundWorker) {
|
||||
logger.error("Background worker not found", { id: backgroundWorkerId });
|
||||
return;
|
||||
}
|
||||
|
||||
const maxCount = env.LEGACY_RUN_ENGINE_WAITING_FOR_DEPLOY_BATCH_SIZE;
|
||||
|
||||
const runsWaitingForDeploy = await this.runStore.findRuns(
|
||||
{
|
||||
where: {
|
||||
runtimeEnvironmentId: backgroundWorker.runtimeEnvironmentId,
|
||||
projectId: backgroundWorker.projectId,
|
||||
status: "WAITING_FOR_DEPLOY",
|
||||
taskIdentifier: {
|
||||
in: backgroundWorker.tasks.map((task) => task.slug),
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "asc",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
status: true,
|
||||
taskIdentifier: true,
|
||||
concurrencyKey: true,
|
||||
queue: true,
|
||||
updatedAt: true,
|
||||
createdAt: true,
|
||||
},
|
||||
take: maxCount + 1,
|
||||
},
|
||||
this._replica
|
||||
);
|
||||
|
||||
if (!runsWaitingForDeploy.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Defense-in-depth: the open-predicate findRuns fan-out can select runs from
|
||||
// either DB, but the status flip below is a single control-plane updateMany. A
|
||||
// run-ops id (NEW-resident) run can only reach WAITING_FOR_DEPLOY via a misconfiguration
|
||||
// (it is a V1/cuid-only status — V2 uses PENDING_VERSION). Surface it loudly rather
|
||||
// than silently strand the run, and only mutate the LEGACY-resident runs the
|
||||
// control-plane client can actually reach.
|
||||
const newResidentRuns = runsWaitingForDeploy.filter((run) => ownerEngine(run.id) === "NEW");
|
||||
if (newResidentRuns.length) {
|
||||
logger.error(
|
||||
"WAITING_FOR_DEPLOY selected NEW-resident runs; skipping their control-plane status flip",
|
||||
{ runIds: newResidentRuns.map((run) => run.id) }
|
||||
);
|
||||
}
|
||||
const legacyRuns = runsWaitingForDeploy.filter((run) => !newResidentRuns.includes(run));
|
||||
|
||||
const pendingRuns = await this._prisma.taskRun.updateMany({
|
||||
where: {
|
||||
id: {
|
||||
in: legacyRuns.map((run) => run.id),
|
||||
},
|
||||
},
|
||||
data: {
|
||||
status: "PENDING",
|
||||
},
|
||||
});
|
||||
|
||||
if (pendingRuns.count) {
|
||||
logger.debug("Task runs waiting for deploy are now ready for execution", {
|
||||
tasks: legacyRuns.map((run) => run.id),
|
||||
total: pendingRuns.count,
|
||||
});
|
||||
}
|
||||
|
||||
// Only enqueue the runs whose status was actually flipped (the legacy set) — never
|
||||
// marqs-enqueue a NEW-resident run we couldn't transition out of WAITING_FOR_DEPLOY.
|
||||
for (const run of legacyRuns) {
|
||||
await marqs?.enqueueMessage(
|
||||
backgroundWorker.runtimeEnvironment,
|
||||
run.queue,
|
||||
run.id,
|
||||
{
|
||||
type: "EXECUTE",
|
||||
taskIdentifier: run.taskIdentifier,
|
||||
projectId: backgroundWorker.runtimeEnvironment.projectId,
|
||||
environmentId: backgroundWorker.runtimeEnvironment.id,
|
||||
environmentType: backgroundWorker.runtimeEnvironment.type,
|
||||
},
|
||||
run.concurrencyKey ?? undefined
|
||||
);
|
||||
}
|
||||
|
||||
if (runsWaitingForDeploy.length > maxCount) {
|
||||
await ExecuteTasksWaitingForDeployService.enqueue(
|
||||
backgroundWorkerId,
|
||||
new Date(Date.now() + env.LEGACY_RUN_ENGINE_WAITING_FOR_DEPLOY_BATCH_STAGGER_MS)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static async enqueue(backgroundWorkerId: string, runAt?: Date) {
|
||||
return await commonWorker.enqueue({
|
||||
id: `v3.executeTasksWaitingForDeploy:${backgroundWorkerId}`,
|
||||
job: "v3.executeTasksWaitingForDeploy",
|
||||
payload: {
|
||||
backgroundWorkerId,
|
||||
},
|
||||
availableAt: runAt,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user