-
-
Notifications
You must be signed in to change notification settings - Fork 724
fix: removing schedule instance no longer crashes #1430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,7 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Prisma, TaskSchedule } from "@trigger.dev/database"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import cronstrue from "cronstrue"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { nanoid } from "nanoid"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { $transaction, PrismaClientOrTransaction } from "~/db.server"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { $transaction } from "~/db.server"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { generateFriendlyId } from "../friendlyIdentifiers"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { UpsertSchedule } from "../schedules"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import { calculateNextScheduledTimestamp } from "../utils/calculateNextSchedule.server"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -31,124 +31,45 @@ export class UpsertTaskScheduleService extends BaseService { | |||||||||||||||||||||||||||||||||||||||||||||||||||
const checkSchedule = new CheckScheduleService(this._prisma); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await checkSchedule.call(projectId, schedule); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const result = await $transaction(this._prisma, async (tx) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const deduplicationKey = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
typeof schedule.deduplicationKey === "string" && schedule.deduplicationKey !== "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
? schedule.deduplicationKey | ||||||||||||||||||||||||||||||||||||||||||||||||||||
: nanoid(24); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const deduplicationKey = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
typeof schedule.deduplicationKey === "string" && schedule.deduplicationKey !== "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
? schedule.deduplicationKey | ||||||||||||||||||||||||||||||||||||||||||||||||||||
: nanoid(24); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const existingSchedule = schedule.friendlyId | ||||||||||||||||||||||||||||||||||||||||||||||||||||
? await tx.taskSchedule.findUnique({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
friendlyId: schedule.friendlyId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
: await tx.taskSchedule.findUnique({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId_deduplicationKey: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
deduplicationKey, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const existingSchedule = schedule.friendlyId | ||||||||||||||||||||||||||||||||||||||||||||||||||||
? await this._prisma.taskSchedule.findUnique({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
friendlyId: schedule.friendlyId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
: await this._prisma.taskSchedule.findUnique({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId_deduplicationKey: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
deduplicationKey, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const result = await (async (tx) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if (existingSchedule) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if (existingSchedule.type === "DECLARATIVE") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new ServiceValidationError("Cannot update a declarative schedule"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return await this.#updateExistingSchedule(tx, existingSchedule, schedule, projectId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return await this.#updateExistingSchedule(existingSchedule, schedule); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return await this.#createNewSchedule(tx, schedule, projectId, deduplicationKey); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return await this.#createNewSchedule(schedule, projectId, deduplicationKey); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
})(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+54
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove unused parameter The parameter Apply this diff to remove the unused parameter: - const result = await (async (tx) => {
+ const result = await (async () => {
if (existingSchedule) {
if (existingSchedule.type === "DECLARATIVE") {
throw new ServiceValidationError("Cannot update a declarative schedule");
}
return await this.#updateExistingSchedule(existingSchedule, schedule);
} else {
return await this.#createNewSchedule(schedule, projectId, deduplicationKey);
}
})(); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!result) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new Error("Failed to create or update the schedule"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const { scheduleRecord, instances } = result; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return this.#createReturnObject(scheduleRecord, instances); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
async #createNewSchedule( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
tx: PrismaClientOrTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
options: UpsertTaskScheduleServiceOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
deduplicationKey: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const scheduleRecord = await tx.taskSchedule.create({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
friendlyId: generateFriendlyId("sched"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskIdentifier: options.taskIdentifier, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
deduplicationKey, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
userProvidedDeduplicationKey: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
options.deduplicationKey !== undefined && options.deduplicationKey !== "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorExpression: options.cron, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorDescription: cronstrue.toString(options.cron), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
timezone: options.timezone ?? "UTC", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
externalId: options.externalId ? options.externalId : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const registerNextService = new RegisterNextTaskScheduleInstanceService(tx); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
//create the instances (links to environments) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let instances: InstanceWithEnvironment[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const environmentId of options.environments) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const instance = await tx.taskScheduleInstance.create({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskScheduleId: scheduleRecord.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
environmentId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
environment: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
orgMember: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
user: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
await registerNextService.call(instance.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
instances.push(instance); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new ServiceValidationError("Failed to create or update schedule"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return { scheduleRecord, instances }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const { scheduleRecord } = result; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
async #updateExistingSchedule( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
tx: PrismaClientOrTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
existingSchedule: TaskSchedule, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
options: UpsertTaskScheduleServiceOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
//update the schedule | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const scheduleRecord = await tx.taskSchedule.update({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
id: existingSchedule.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorExpression: options.cron, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorDescription: cronstrue.toString(options.cron), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
timezone: options.timezone ?? "UTC", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
externalId: options.externalId ? options.externalId : null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const scheduleHasChanged = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
scheduleRecord.generatorExpression !== existingSchedule.generatorExpression || | ||||||||||||||||||||||||||||||||||||||||||||||||||||
scheduleRecord.timezone !== existingSchedule.timezone; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// find the existing instances | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const existingInstances = await tx.taskScheduleInstance.findMany({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const instances = await this._prisma.taskScheduleInstance.findMany({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskScheduleId: scheduleRecord.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -165,18 +86,35 @@ export class UpsertTaskScheduleService extends BaseService { | |||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// create the new instances | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const newInstances: InstanceWithEnvironment[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const updatingInstances: InstanceWithEnvironment[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return this.#createReturnObject(scheduleRecord, instances); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
async #createNewSchedule( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
options: UpsertTaskScheduleServiceOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
deduplicationKey: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return await $transaction(this._prisma, async (tx) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const scheduleRecord = await tx.taskSchedule.create({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
projectId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
friendlyId: generateFriendlyId("sched"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskIdentifier: options.taskIdentifier, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
deduplicationKey, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
userProvidedDeduplicationKey: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
options.deduplicationKey !== undefined && options.deduplicationKey !== "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorExpression: options.cron, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorDescription: cronstrue.toString(options.cron), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
timezone: options.timezone ?? "UTC", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
externalId: options.externalId ? options.externalId : undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const registerNextService = new RegisterNextTaskScheduleInstanceService(tx); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const environmentId of options.environments) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const existingInstance = existingInstances.find((i) => i.environmentId === environmentId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
//create the instances (links to environments) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if (existingInstance) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// Update the existing instance | ||||||||||||||||||||||||||||||||||||||||||||||||||||
updatingInstances.push(existingInstance); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// Create a new instance | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const environmentId of options.environments) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const instance = await tx.taskScheduleInstance.create({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskScheduleId: scheduleRecord.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -195,39 +133,21 @@ export class UpsertTaskScheduleService extends BaseService { | |||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
newInstances.push(instance); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await registerNextService.call(instance.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// find the instances that need to be removed | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const instancesToDeleted = existingInstances.filter( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(i) => !options.environments.includes(i.environmentId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// delete the instances no longer selected | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const instance of instancesToDeleted) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await tx.taskScheduleInstance.delete({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
id: instance.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const registerService = new RegisterNextTaskScheduleInstanceService(tx); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const instance of newInstances) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await registerService.call(instance.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if (scheduleHasChanged) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const instance of updatingInstances) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await registerService.call(instance.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return { scheduleRecord }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const instances = await tx.taskScheduleInstance.findMany({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
async #updateExistingSchedule( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
existingSchedule: TaskSchedule, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
options: UpsertTaskScheduleServiceOptions | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// find the existing instances | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const existingInstances = await this._prisma.taskScheduleInstance.findMany({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskScheduleId: scheduleRecord.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskScheduleId: existingSchedule.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
environment: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -242,7 +162,89 @@ export class UpsertTaskScheduleService extends BaseService { | |||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return { scheduleRecord, instances }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return await $transaction( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this._prisma, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
async (tx) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const scheduleRecord = await tx.taskSchedule.update({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
id: existingSchedule.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorExpression: options.cron, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
generatorDescription: cronstrue.toString(options.cron), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
timezone: options.timezone ?? "UTC", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
externalId: options.externalId ? options.externalId : null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const scheduleHasChanged = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
scheduleRecord.generatorExpression !== existingSchedule.generatorExpression || | ||||||||||||||||||||||||||||||||||||||||||||||||||||
scheduleRecord.timezone !== existingSchedule.timezone; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// create the new instances | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const newInstances: InstanceWithEnvironment[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const updatingInstances: InstanceWithEnvironment[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const environmentId of options.environments) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const existingInstance = existingInstances.find((i) => i.environmentId === environmentId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if (existingInstance) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// Update the existing instance | ||||||||||||||||||||||||||||||||||||||||||||||||||||
updatingInstances.push(existingInstance); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// Create a new instance | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const instance = await tx.taskScheduleInstance.create({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
data: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
taskScheduleId: scheduleRecord.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
environmentId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
environment: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
orgMember: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
include: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
user: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
newInstances.push(instance); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// find the instances that need to be removed | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const instancesToDeleted = existingInstances.filter( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(i) => !options.environments.includes(i.environmentId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+219
to
+221
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct variable name from There's a typo in the variable name Apply this diff to fix the typo: // find the instances that need to be removed
- const instancesToDeleted = existingInstances.filter(
+ const instancesToDelete = existingInstances.filter(
(i) => !options.environments.includes(i.environmentId)
);
// delete the instances no longer selected
- for (const instance of instancesToDeleted) {
+ for (const instance of instancesToDelete) {
await tx.taskScheduleInstance.delete({
where: {
id: instance.id,
},
});
} Also applies to: 224-230 |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// delete the instances no longer selected | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const instance of instancesToDeleted) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await tx.taskScheduleInstance.delete({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
where: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
id: instance.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
const registerService = new RegisterNextTaskScheduleInstanceService(tx); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const instance of newInstances) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await registerService.call(instance.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if (scheduleHasChanged) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const instance of updatingInstances) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
await registerService.call(instance.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
return { scheduleRecord }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
{ timeout: 10_000 } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
#createReturnObject(taskSchedule: TaskSchedule, instances: InstanceWithEnvironment[]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-- CreateIndex | ||
CREATE INDEX CONCURRENTLY IF NOT EXISTS "TaskRun_scheduleInstanceId_idx" ON "TaskRun"("scheduleInstanceId"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve error handling with error categorization.
While the current changes improve security by not exposing internal errors to users, consider categorizing known errors to provide more specific user feedback when appropriate.
Consider implementing error categorization like this:
This approach: