Skip to content

Commit ddd000b

Browse files
committed
fix: respect max elapsed in backoff execute
1 parent 37eeaa3 commit ddd000b

3 files changed

Lines changed: 40 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
Stop `ExponentialBackoff.execute()` retries when callback execution time pushes the run past `maxElapsed`.

packages/core/src/v3/apps/backoff.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ export class ExponentialBackoff {
9898
return this.#clone(undefined, { maxRetries });
9999
}
100100

101-
// TODO: With .execute(), should this also include the time it takes to execute the callback?
102101
maxElapsed(maxElapsed?: number) {
103102
return this.#clone(undefined, { maxElapsed });
104103
}
@@ -340,6 +339,14 @@ export class ExponentialBackoff {
340339
elapsedMs += Date.now() - start;
341340
clearTimeout(attemptTimeout);
342341
}
342+
343+
if (elapsedMs / 1000 > this.#maxElapsed) {
344+
return {
345+
success: false,
346+
cause: "Timeout",
347+
error: finalError,
348+
};
349+
}
343350
}
344351

345352
if (finalError instanceof AttemptTimeout) {

packages/core/test/backoff.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { describe, expect, it } from "vitest";
2+
import { ExponentialBackoff } from "../src/v3/apps/backoff.js";
3+
4+
describe("ExponentialBackoff", () => {
5+
it("stops execute retries when callback time exceeds maxElapsed", async () => {
6+
const backoff = new ExponentialBackoff("NoJitter", {
7+
factor: 0,
8+
maxElapsed: 0.01,
9+
maxRetries: 5,
10+
});
11+
const error = new Error("retryable");
12+
let attempts = 0;
13+
14+
const result = await backoff.execute(async () => {
15+
attempts++;
16+
await new Promise((resolve) => setTimeout(resolve, 25));
17+
throw error;
18+
});
19+
20+
expect(result).toEqual({
21+
success: false,
22+
cause: "Timeout",
23+
error,
24+
});
25+
expect(attempts).toBe(1);
26+
});
27+
});

0 commit comments

Comments
 (0)