Skip to content

Commit 5865354

Browse files
committed
Add ability to opt-out of maxDuration with timeout.None
1 parent 391140a commit 5865354

File tree

9 files changed

+50
-13
lines changed

9 files changed

+50
-13
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { eventRepository } from "~/v3/eventRepository.server";
99
import { machinePresetFromName } from "~/v3/machinePresets.server";
1010
import { FINAL_ATTEMPT_STATUSES, isFinalRunStatus } from "~/v3/taskStatus";
1111
import { BasePresenter } from "./basePresenter.server";
12+
import { getMaxDuration } from "~/v3/utils/maxDuration";
1213

1314
type Result = Awaited<ReturnType<SpanPresenter["call"]>>;
1415
export type Span = NonNullable<NonNullable<Result>["span"]>;
@@ -309,7 +310,7 @@ export class SpanPresenter extends BasePresenter {
309310
},
310311
context: JSON.stringify(context, null, 2),
311312
metadata,
312-
maxDurationInSeconds: run.maxDurationInSeconds,
313+
maxDurationInSeconds: getMaxDuration(run.maxDurationInSeconds),
313314
};
314315
}
315316

apps/webapp/app/v3/marqs/devQueueConsumer.server.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
tracer,
2525
} from "../tracer.server";
2626
import { DevSubscriber, devPubSub } from "./devPubSub.server";
27+
import { getMaxDuration } from "../utils/maxDuration";
2728

2829
const MessageBody = z.discriminatedUnion("type", [
2930
z.object({
@@ -378,8 +379,10 @@ export class DevQueueConsumer {
378379
status: "EXECUTING",
379380
lockedToVersionId: backgroundWorker.id,
380381
startedAt: existingTaskRun.startedAt ?? new Date(),
381-
maxDurationInSeconds:
382-
existingTaskRun.maxDurationInSeconds ?? backgroundTask.maxDurationInSeconds,
382+
maxDurationInSeconds: getMaxDuration(
383+
existingTaskRun.maxDurationInSeconds,
384+
backgroundTask.maxDurationInSeconds
385+
),
383386
},
384387
include: {
385388
attempts: {

apps/webapp/app/v3/marqs/sharedQueueConsumer.server.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { EnvironmentVariable } from "../environmentVariables/repository";
4444
import { machinePresetFromConfig } from "../machinePresets.server";
4545
import { env } from "~/env.server";
4646
import { isFinalAttemptStatus, isFinalRunStatus } from "../taskStatus";
47+
import { getMaxDuration } from "../utils/maxDuration";
4748

4849
const WithTraceContext = z.object({
4950
traceparent: z.string().optional(),
@@ -403,8 +404,10 @@ export class SharedQueueConsumer {
403404
startedAt: existingTaskRun.startedAt ?? new Date(),
404405
baseCostInCents: env.CENTS_PER_RUN,
405406
machinePreset: machinePresetFromConfig(backgroundTask.machineConfig ?? {}).name,
406-
maxDurationInSeconds:
407-
existingTaskRun.maxDurationInSeconds ?? backgroundTask.maxDurationInSeconds,
407+
maxDurationInSeconds: getMaxDuration(
408+
existingTaskRun.maxDurationInSeconds,
409+
backgroundTask.maxDurationInSeconds
410+
),
408411
},
409412
include: {
410413
runtimeEnvironment: true,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { projectPubSub } from "./projectPubSub.server";
1515
import { RegisterNextTaskScheduleInstanceService } from "./registerNextTaskScheduleInstance.server";
1616
import cronstrue from "cronstrue";
1717
import { CheckScheduleService } from "./checkSchedule.server";
18+
import { clampMaxDuration } from "../utils/maxDuration";
1819

1920
export class CreateBackgroundWorkerService extends BaseService {
2021
public async call(
@@ -156,7 +157,7 @@ export async function createBackgroundTasks(
156157
machineConfig: task.machine,
157158
triggerSource: task.triggerSource === "schedule" ? "SCHEDULED" : "STANDARD",
158159
fileId: tasksToBackgroundFiles?.get(task.id) ?? null,
159-
maxDurationInSeconds: task.maxDuration ? Math.max(task.maxDuration, 5) : null,
160+
maxDurationInSeconds: task.maxDuration ? clampMaxDuration(task.maxDuration) : null,
160161
},
161162
});
162163

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { findCurrentWorkerFromEnvironment } from "../models/workerDeployment.ser
2323
import { handleMetadataPacket } from "~/utils/packets";
2424
import { ExpireEnqueuedRunService } from "./expireEnqueuedRun.server";
2525
import { guardQueueSizeLimitsForEnv } from "../queueSizeLimits.server";
26+
import { clampMaxDuration } from "../utils/maxDuration";
2627

2728
export type TriggerTaskServiceOptions = {
2829
idempotencyKey?: string;
@@ -374,7 +375,7 @@ export class TriggerTaskService extends BaseService {
374375
seedMetadata: metadataPacket?.data,
375376
seedMetadataType: metadataPacket?.dataType,
376377
maxDurationInSeconds: body.options?.maxDuration
377-
? Math.max(body.options.maxDuration, 5)
378+
? clampMaxDuration(body.options.maxDuration)
378379
: undefined,
379380
},
380381
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const MINIMUM_MAX_DURATION = 5;
2+
const MAXIMUM_MAX_DURATION = 2_147_483_647; // largest 32-bit signed integer
3+
4+
export function clampMaxDuration(maxDuration: number): number {
5+
return Math.min(Math.max(maxDuration, MINIMUM_MAX_DURATION), MAXIMUM_MAX_DURATION);
6+
}
7+
8+
export function getMaxDuration(
9+
maxDuration?: number | null,
10+
defaultMaxDuration?: number | null
11+
): number | undefined {
12+
if (!maxDuration) {
13+
return defaultMaxDuration ?? undefined;
14+
}
15+
16+
// Setting the maxDuration to MAXIMUM_MAX_DURATION means we don't want to use the default maxDuration
17+
if (maxDuration === MAXIMUM_MAX_DURATION) {
18+
return;
19+
}
20+
21+
return maxDuration;
22+
}

packages/trigger-sdk/src/v3/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export * from "./usage.js";
88
export * from "./idempotencyKeys.js";
99
export * from "./tags.js";
1010
export * from "./metadata.js";
11+
export * from "./timeout.js";
1112
export type { Context };
1213

1314
import type { Context } from "./shared.js";
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { timeout as timeoutApi } from "@trigger.dev/core/v3";
2+
3+
const MAXIMUM_MAX_DURATION = 2_147_483_647;
4+
5+
export const timeout = {
6+
None: MAXIMUM_MAX_DURATION,
7+
signal: timeoutApi.signal,
8+
};

references/hello-world/src/trigger/example.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { logger, task, usage, wait } from "@trigger.dev/sdk/v3";
1+
import { logger, task, timeout, usage, wait } from "@trigger.dev/sdk/v3";
22
import { setTimeout } from "timers/promises";
33

44
export const helloWorldTask = task({
@@ -51,12 +51,9 @@ export const maxDurationTask = task({
5151
maxTimeoutInMs: 2_000,
5252
factor: 1.4,
5353
},
54+
maxDuration: 5,
5455
run: async (payload: { sleepFor: number }, { signal, ctx }) => {
5556
await setTimeout(payload.sleepFor * 1000, { signal });
56-
57-
if (ctx.attempt.number < 5) {
58-
throw new Error("Example error");
59-
}
6057
},
6158
});
6259

@@ -65,7 +62,7 @@ export const maxDurationParentTask = task({
6562
run: async (payload: { sleepFor?: number; maxDuration?: number }, { ctx, signal }) => {
6663
const result = await maxDurationTask.triggerAndWait(
6764
{ sleepFor: payload.sleepFor ?? 10 },
68-
{ maxDuration: payload.maxDuration ?? 600 }
65+
{ maxDuration: timeout.None }
6966
);
7067

7168
return result;

0 commit comments

Comments
 (0)