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 <james@trigger.dev>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<Note>
|
||||
In the Trigger.dev Cloud we automatically pause execution of tasks when they are waiting for
|
||||
longer than a few seconds. You are not charged when execution is paused.
|
||||
</Note>
|
||||
In the Trigger.dev Cloud we automatically pause execution of tasks when they are waiting for
|
||||
longer than a few seconds.
|
||||
|
||||
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.
|
||||
@@ -369,6 +369,14 @@ export class WaitpointTimeoutError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
const DURATION_WAIT_CHARGE_THRESHOLD_MS = 5000;
|
||||
|
||||
function printWaitBelowThreshold() {
|
||||
console.warn(
|
||||
`Waits of ${DURATION_WAIT_CHARGE_THRESHOLD_MS / 1000}s or less count towards compute usage.`
|
||||
);
|
||||
}
|
||||
|
||||
export const wait = {
|
||||
for: async (options: WaitForOptions) => {
|
||||
const ctx = taskContext.ctx;
|
||||
@@ -380,6 +388,36 @@ export const wait = {
|
||||
|
||||
const start = Date.now();
|
||||
const durationInMs = calculateDurationInMs(options);
|
||||
|
||||
if (durationInMs <= DURATION_WAIT_CHARGE_THRESHOLD_MS) {
|
||||
return tracer.startActiveSpan(
|
||||
`wait.for()`,
|
||||
async (span) => {
|
||||
if (durationInMs <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
printWaitBelowThreshold();
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, durationInMs));
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
[SemanticInternalAttributes.STYLE_ICON]: "wait",
|
||||
...accessoryAttributes({
|
||||
items: [
|
||||
{
|
||||
text: nameForWaitOptions(options),
|
||||
variant: "normal",
|
||||
},
|
||||
],
|
||||
style: "codepath",
|
||||
}),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const date = new Date(start + durationInMs);
|
||||
const result = await apiClient.waitForDuration(ctx.run.id, {
|
||||
date: date,
|
||||
@@ -417,6 +455,46 @@ export const wait = {
|
||||
throw new Error("wait.forToken can only be used from inside a task.run()");
|
||||
}
|
||||
|
||||
// Calculate duration in ms
|
||||
const durationInMs = options.date.getTime() - Date.now();
|
||||
|
||||
if (durationInMs <= DURATION_WAIT_CHARGE_THRESHOLD_MS) {
|
||||
return tracer.startActiveSpan(
|
||||
`wait.for()`,
|
||||
async (span) => {
|
||||
if (durationInMs === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (durationInMs < 0) {
|
||||
if (options.throwIfInThePast) {
|
||||
throw new Error("Date is in the past");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
printWaitBelowThreshold();
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, durationInMs));
|
||||
},
|
||||
{
|
||||
attributes: {
|
||||
[SemanticInternalAttributes.STYLE_ICON]: "wait",
|
||||
...accessoryAttributes({
|
||||
items: [
|
||||
{
|
||||
text: options.date.toISOString(),
|
||||
variant: "normal",
|
||||
},
|
||||
],
|
||||
style: "codepath",
|
||||
}),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const apiClient = apiClientManager.clientOrThrow();
|
||||
|
||||
const result = await apiClient.waitForDuration(ctx.run.id, {
|
||||
|
||||
Reference in New Issue
Block a user