Skip to content

Commit dcf1ab6

Browse files
authored
Remove schedule constraints from TaskRun to prevent db load issues when a schedule or instance is deleted (#1674)
1 parent c49af77 commit dcf1ab6

File tree

7 files changed

+110
-73
lines changed

7 files changed

+110
-73
lines changed

apps/webapp/app/presenters/v3/ApiRetrieveRunPresenter.server.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const commonRunSelect = {
3939
idempotencyKey: true,
4040
isTest: true,
4141
depth: true,
42+
scheduleId: true,
4243
lockedToVersion: {
4344
select: {
4445
version: true,
@@ -71,7 +72,6 @@ export class ApiRetrieveRunPresenter extends BasePresenter {
7172
include: {
7273
attempts: true,
7374
lockedToVersion: true,
74-
schedule: true,
7575
tags: true,
7676
batch: {
7777
select: {
@@ -157,20 +157,7 @@ export class ApiRetrieveRunPresenter extends BasePresenter {
157157
output: $output,
158158
outputPresignedUrl: $outputPresignedUrl,
159159
error: ApiRetrieveRunPresenter.apiErrorFromError(taskRun.error),
160-
schedule: taskRun.schedule
161-
? {
162-
id: taskRun.schedule.friendlyId,
163-
externalId: taskRun.schedule.externalId ?? undefined,
164-
deduplicationKey: taskRun.schedule.userProvidedDeduplicationKey
165-
? taskRun.schedule.deduplicationKey
166-
: undefined,
167-
generator: {
168-
type: "CRON" as const,
169-
expression: taskRun.schedule.generatorExpression,
170-
description: taskRun.schedule.generatorDescription,
171-
},
172-
}
173-
: undefined,
160+
schedule: await resolveSchedule(taskRun),
174161
// We're removing attempts from the API
175162
attemptCount: taskRun.attempts.length,
176163
attempts: [],
@@ -320,6 +307,33 @@ export class ApiRetrieveRunPresenter extends BasePresenter {
320307
}
321308
}
322309

310+
async function resolveSchedule(run: CommonRelatedRun) {
311+
if (!run.scheduleId) {
312+
return undefined;
313+
}
314+
315+
const schedule = await prisma.taskSchedule.findFirst({
316+
where: {
317+
id: run.scheduleId,
318+
},
319+
});
320+
321+
if (!schedule) {
322+
return undefined;
323+
}
324+
325+
return {
326+
id: schedule.friendlyId,
327+
externalId: schedule.externalId ?? undefined,
328+
deduplicationKey: schedule.userProvidedDeduplicationKey ? schedule.deduplicationKey : undefined,
329+
generator: {
330+
type: "CRON" as const,
331+
expression: schedule.generatorExpression,
332+
description: schedule.generatorDescription,
333+
},
334+
};
335+
}
336+
323337
async function createCommonRunStructure(run: CommonRelatedRun) {
324338
const metadata = await parsePacket({
325339
data: run.metadata ?? undefined,

apps/webapp/app/presenters/v3/SpanPresenter.server.ts

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,7 @@ export class SpanPresenter extends BasePresenter {
102102
queue: true,
103103
concurrencyKey: true,
104104
//schedule
105-
schedule: {
106-
select: {
107-
friendlyId: true,
108-
generatorExpression: true,
109-
timezone: true,
110-
generatorDescription: true,
111-
},
112-
},
105+
scheduleId: true,
113106
//usage
114107
baseCostInCents: true,
115108
costInCents: true,
@@ -281,14 +274,7 @@ export class SpanPresenter extends BasePresenter {
281274
sdkVersion: run.lockedToVersion?.sdkVersion,
282275
isTest: run.isTest,
283276
environmentId: run.runtimeEnvironment.id,
284-
schedule: run.schedule
285-
? {
286-
friendlyId: run.schedule.friendlyId,
287-
generatorExpression: run.schedule.generatorExpression,
288-
description: run.schedule.generatorDescription,
289-
timezone: run.schedule.timezone,
290-
}
291-
: undefined,
277+
schedule: await this.resolveSchedule(run.scheduleId ?? undefined),
292278
queue: {
293279
name: run.queue,
294280
isCustomQueue: !run.queue.startsWith("task/"),
@@ -323,6 +309,35 @@ export class SpanPresenter extends BasePresenter {
323309
};
324310
}
325311

312+
async resolveSchedule(scheduleId?: string) {
313+
if (!scheduleId) {
314+
return;
315+
}
316+
317+
const schedule = await this._replica.taskSchedule.findFirst({
318+
where: {
319+
id: scheduleId,
320+
},
321+
select: {
322+
friendlyId: true,
323+
generatorExpression: true,
324+
timezone: true,
325+
generatorDescription: true,
326+
},
327+
});
328+
329+
if (!schedule) {
330+
return;
331+
}
332+
333+
return {
334+
friendlyId: schedule.friendlyId,
335+
generatorExpression: schedule.generatorExpression,
336+
description: schedule.generatorDescription,
337+
timezone: schedule.timezone,
338+
};
339+
}
340+
326341
async getSpan(runFriendlyId: string, spanId: string) {
327342
const run = await this._prisma.taskRun.findFirst({
328343
select: {

apps/webapp/app/routes/resources.runs.$runParam.ts

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
5454
queue: true,
5555
concurrencyKey: true,
5656
//schedule
57-
schedule: {
58-
select: {
59-
friendlyId: true,
60-
generatorExpression: true,
61-
timezone: true,
62-
generatorDescription: true,
63-
},
64-
},
57+
scheduleId: true,
6558
//usage
6659
baseCostInCents: true,
6760
costInCents: true,
@@ -212,14 +205,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
212205
sdkVersion: run.lockedToVersion?.sdkVersion,
213206
isTest: run.isTest,
214207
environmentId: run.runtimeEnvironment.id,
215-
schedule: run.schedule
216-
? {
217-
friendlyId: run.schedule.friendlyId,
218-
generatorExpression: run.schedule.generatorExpression,
219-
description: run.schedule.generatorDescription,
220-
timezone: run.schedule.timezone,
221-
}
222-
: undefined,
208+
schedule: await resolveSchedule(run.scheduleId ?? undefined),
223209
queue: {
224210
name: run.queue,
225211
isCustomQueue: !run.queue.startsWith("task/"),
@@ -240,3 +226,32 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
240226
context: JSON.stringify(context, null, 2),
241227
});
242228
};
229+
230+
async function resolveSchedule(scheduleId?: string) {
231+
if (!scheduleId) {
232+
return;
233+
}
234+
235+
const schedule = await $replica.taskSchedule.findFirst({
236+
where: {
237+
id: scheduleId,
238+
},
239+
select: {
240+
friendlyId: true,
241+
generatorExpression: true,
242+
timezone: true,
243+
generatorDescription: true,
244+
},
245+
});
246+
247+
if (!schedule) {
248+
return;
249+
}
250+
251+
return {
252+
friendlyId: schedule.friendlyId,
253+
generatorExpression: schedule.generatorExpression,
254+
description: schedule.generatorDescription,
255+
timezone: schedule.timezone,
256+
};
257+
}

apps/webapp/app/v3/services/deleteTaskSchedule.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class DeleteTaskScheduleService extends BaseService {
4343

4444
await this._prisma.taskSchedule.delete({
4545
where: {
46-
friendlyId,
46+
id: schedule.id,
4747
},
4848
});
4949
} catch (e) {

apps/webapp/app/v3/services/triggerScheduledTask.server.ts

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ export class TriggerScheduledTaskService extends BaseService {
3232
return;
3333
}
3434

35+
if (instance.environment.organization.deletedAt) {
36+
logger.debug("Organization is deleted, disabling schedule", {
37+
instanceId,
38+
scheduleId: instance.taskSchedule.friendlyId,
39+
organizationId: instance.environment.organization.id,
40+
});
41+
42+
return;
43+
}
44+
3545
try {
3646
let shouldTrigger = true;
3747

@@ -40,23 +50,6 @@ export class TriggerScheduledTaskService extends BaseService {
4050
}
4151

4252
if (!instance.taskSchedule.active) {
43-
shouldTrigger = false;
44-
} else if (instance.environment.organization.deletedAt) {
45-
logger.debug("Organization is deleted, disabling schedule", {
46-
instanceId,
47-
scheduleId: instance.taskSchedule.friendlyId,
48-
organizationId: instance.environment.organization.id,
49-
});
50-
51-
await this._prisma.taskSchedule.update({
52-
where: {
53-
id: instance.taskSchedule.id,
54-
},
55-
data: {
56-
active: false,
57-
},
58-
});
59-
6053
shouldTrigger = false;
6154
}
6255

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- DropForeignKey
2+
ALTER TABLE
3+
"TaskRun" DROP CONSTRAINT IF EXISTS "TaskRun_scheduleId_fkey";
4+
5+
-- DropForeignKey
6+
ALTER TABLE
7+
"TaskRun" DROP CONSTRAINT IF EXISTS "TaskRun_scheduleInstanceId_fkey";

internal-packages/database/prisma/schema.prisma

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,11 +1735,8 @@ model TaskRun {
17351735
17361736
alerts ProjectAlert[]
17371737
1738-
scheduleInstance TaskScheduleInstance? @relation(fields: [scheduleInstanceId], references: [id], onDelete: SetNull)
17391738
scheduleInstanceId String?
1740-
1741-
schedule TaskSchedule? @relation(fields: [scheduleId], references: [id], onDelete: SetNull)
1742-
scheduleId String?
1739+
scheduleId String?
17431740
17441741
sourceBulkActionItems BulkActionItem[] @relation("SourceActionItemRun")
17451742
destinationBulkActionItems BulkActionItem[] @relation("DestinationActionItemRun")
@@ -2452,8 +2449,6 @@ model TaskSchedule {
24522449
24532450
active Boolean @default(true)
24542451
2455-
runs TaskRun[]
2456-
24572452
@@unique([projectId, deduplicationKey])
24582453
}
24592454

@@ -2486,8 +2481,6 @@ model TaskScheduleInstance {
24862481
lastScheduledTimestamp DateTime?
24872482
nextScheduledTimestamp DateTime?
24882483
2489-
runs TaskRun[]
2490-
24912484
//you can only have a schedule attached to each environment once
24922485
@@unique([taskScheduleId, environmentId])
24932486
}

0 commit comments

Comments
 (0)