101 lines
2.7 KiB
TypeScript
101 lines
2.7 KiB
TypeScript
import { $transaction, type PrismaClientOrTransaction, prisma } from "~/db.server";
|
|
import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
|
|
import { logger } from "~/services/logger.server";
|
|
import { isCancellableRunStatus } from "../taskStatus";
|
|
import { BaseService } from "./baseService.server";
|
|
import { FinalizeTaskRunService } from "./finalizeTaskRun.server";
|
|
|
|
export class CancelAttemptService extends BaseService {
|
|
public async call(
|
|
attemptId: string,
|
|
taskRunId: string,
|
|
cancelledAt: Date,
|
|
reason: string,
|
|
env?: AuthenticatedEnvironment
|
|
) {
|
|
let environment: AuthenticatedEnvironment | undefined = env;
|
|
|
|
if (!environment) {
|
|
environment = await getAuthenticatedEnvironmentFromAttempt(attemptId);
|
|
|
|
if (!environment) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
return await this.traceWithEnv("call()", environment, async (span) => {
|
|
span.setAttribute("taskRunId", taskRunId);
|
|
span.setAttribute("attemptId", attemptId);
|
|
|
|
const taskRunAttempt = await this._prisma.taskRunAttempt.findFirst({
|
|
where: {
|
|
friendlyId: attemptId,
|
|
},
|
|
include: {
|
|
taskRun: true,
|
|
},
|
|
});
|
|
|
|
if (!taskRunAttempt) {
|
|
return;
|
|
}
|
|
|
|
if (taskRunAttempt.status === "CANCELED") {
|
|
logger.warn("Task run attempt is already cancelled", {
|
|
attemptId,
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
await $transaction(this._prisma, "cancel attempt", async (tx) => {
|
|
await tx.taskRunAttempt.update({
|
|
where: {
|
|
friendlyId: attemptId,
|
|
},
|
|
data: {
|
|
status: "CANCELED",
|
|
completedAt: cancelledAt,
|
|
},
|
|
});
|
|
|
|
const isCancellable = isCancellableRunStatus(taskRunAttempt.taskRun.status);
|
|
|
|
const finalizeService = new FinalizeTaskRunService(tx);
|
|
await finalizeService.call({
|
|
id: taskRunId,
|
|
status: isCancellable ? "INTERRUPTED" : undefined,
|
|
completedAt: isCancellable ? cancelledAt : undefined,
|
|
attemptStatus: isCancellable ? "CANCELED" : undefined,
|
|
error: isCancellable ? { type: "STRING_ERROR", raw: reason } : undefined,
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
async function getAuthenticatedEnvironmentFromAttempt(
|
|
friendlyId: string,
|
|
prismaClient?: PrismaClientOrTransaction
|
|
) {
|
|
const taskRunAttempt = await (prismaClient ?? prisma).taskRunAttempt.findFirst({
|
|
where: {
|
|
friendlyId,
|
|
},
|
|
include: {
|
|
runtimeEnvironment: {
|
|
include: {
|
|
organization: true,
|
|
project: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!taskRunAttempt) {
|
|
return;
|
|
}
|
|
|
|
return taskRunAttempt?.runtimeEnvironment;
|
|
}
|