Skip to content

Commit a9d5646

Browse files
nicktrnsamejr
andauthored
Very short waits count towards compute usage (#1888)
* add duration wait threshold * improve wording * Updates the wait overview, wait.for and wait.until pages copy to better explain compute costs --------- Co-authored-by: James Ritchie <[email protected]>
1 parent 32d2992 commit a9d5646

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Note>
2-
In the Trigger.dev Cloud we automatically pause execution of tasks when they are waiting for
3-
longer than a few seconds. You are not charged when execution is paused.
4-
</Note>
1+
In the Trigger.dev Cloud we automatically pause execution of tasks when they are waiting for
2+
longer than a few seconds.
3+
4+
When triggering and waiting for subtasks, the parent is checkpointed and while waiting does not count towards compute usage. When waiting for a time period (`wait.for` or `wait.until`), if the wait is longer than 5 seconds we checkpoint and it does not count towards compute usage.

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

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,14 @@ export class WaitpointTimeoutError extends Error {
369369
}
370370
}
371371

372+
const DURATION_WAIT_CHARGE_THRESHOLD_MS = 5000;
373+
374+
function printWaitBelowThreshold() {
375+
console.warn(
376+
`Waits of ${DURATION_WAIT_CHARGE_THRESHOLD_MS / 1000}s or less count towards compute usage.`
377+
);
378+
}
379+
372380
export const wait = {
373381
for: async (options: WaitForOptions) => {
374382
const ctx = taskContext.ctx;
@@ -380,6 +388,36 @@ export const wait = {
380388

381389
const start = Date.now();
382390
const durationInMs = calculateDurationInMs(options);
391+
392+
if (durationInMs <= DURATION_WAIT_CHARGE_THRESHOLD_MS) {
393+
return tracer.startActiveSpan(
394+
`wait.for()`,
395+
async (span) => {
396+
if (durationInMs <= 0) {
397+
return;
398+
}
399+
400+
printWaitBelowThreshold();
401+
402+
await new Promise((resolve) => setTimeout(resolve, durationInMs));
403+
},
404+
{
405+
attributes: {
406+
[SemanticInternalAttributes.STYLE_ICON]: "wait",
407+
...accessoryAttributes({
408+
items: [
409+
{
410+
text: nameForWaitOptions(options),
411+
variant: "normal",
412+
},
413+
],
414+
style: "codepath",
415+
}),
416+
},
417+
}
418+
);
419+
}
420+
383421
const date = new Date(start + durationInMs);
384422
const result = await apiClient.waitForDuration(ctx.run.id, {
385423
date: date,
@@ -417,6 +455,46 @@ export const wait = {
417455
throw new Error("wait.forToken can only be used from inside a task.run()");
418456
}
419457

458+
// Calculate duration in ms
459+
const durationInMs = options.date.getTime() - Date.now();
460+
461+
if (durationInMs <= DURATION_WAIT_CHARGE_THRESHOLD_MS) {
462+
return tracer.startActiveSpan(
463+
`wait.for()`,
464+
async (span) => {
465+
if (durationInMs === 0) {
466+
return;
467+
}
468+
469+
if (durationInMs < 0) {
470+
if (options.throwIfInThePast) {
471+
throw new Error("Date is in the past");
472+
}
473+
474+
return;
475+
}
476+
477+
printWaitBelowThreshold();
478+
479+
await new Promise((resolve) => setTimeout(resolve, durationInMs));
480+
},
481+
{
482+
attributes: {
483+
[SemanticInternalAttributes.STYLE_ICON]: "wait",
484+
...accessoryAttributes({
485+
items: [
486+
{
487+
text: options.date.toISOString(),
488+
variant: "normal",
489+
},
490+
],
491+
style: "codepath",
492+
}),
493+
},
494+
}
495+
);
496+
}
497+
420498
const apiClient = apiClientManager.clientOrThrow();
421499

422500
const result = await apiClient.waitForDuration(ctx.run.id, {

0 commit comments

Comments
 (0)