From 916a353660e251946d76bdf565c26b7801d3beb8 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Mon, 28 Aug 2023 10:16:47 +0100 Subject: [PATCH] bugfix: retrying tasks no longer incorrectly complete successfully --- .changeset/dry-spoons-accept.md | 5 +++ .../runs/performRunExecutionV2.server.ts | 4 +- examples/job-catalog/src/events.ts | 42 +++++++++++++++++++ packages/trigger-sdk/src/io.ts | 4 +- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 .changeset/dry-spoons-accept.md diff --git a/.changeset/dry-spoons-accept.md b/.changeset/dry-spoons-accept.md new file mode 100644 index 000000000..72fd77d4a --- /dev/null +++ b/.changeset/dry-spoons-accept.md @@ -0,0 +1,5 @@ +--- +"@trigger.dev/sdk": patch +--- + +Only use cached tasks if they are completed, otherwise retrying tasks will be considered successful diff --git a/apps/webapp/app/services/runs/performRunExecutionV2.server.ts b/apps/webapp/app/services/runs/performRunExecutionV2.server.ts index b8e5cfe62..95d2bce6b 100644 --- a/apps/webapp/app/services/runs/performRunExecutionV2.server.ts +++ b/apps/webapp/app/services/runs/performRunExecutionV2.server.ts @@ -477,7 +477,9 @@ export class PerformRunExecutionV2Service { } } -function prepareTasksForRun(tasks: FoundTask[]): CachedTask[] { +function prepareTasksForRun(possibleTasks: FoundTask[]): CachedTask[] { + const tasks = possibleTasks.filter((task) => task.status === "COMPLETED"); + // We need to limit the cached tasks to not be too large >3.5MB when serialized const TOTAL_CACHED_TASK_BYTE_LIMIT = 3500000; diff --git a/examples/job-catalog/src/events.ts b/examples/job-catalog/src/events.ts index cc6656bcb..fd611f0be 100644 --- a/examples/job-catalog/src/events.ts +++ b/examples/job-catalog/src/events.ts @@ -1,5 +1,6 @@ import { createExpressServer } from "@trigger.dev/express"; import { TriggerClient, eventTrigger } from "@trigger.dev/sdk"; +import { z } from "zod"; export const client = new TriggerClient({ id: "job-catalog", @@ -56,4 +57,45 @@ client.defineJob({ }, }); +client.defineJob({ + id: "example-job", + name: "Example Job: a joke with a delay", + version: "0.0.2", + trigger: eventTrigger({ + name: "shayan.event", + schema: z.object({ + userId: z.string(), + delay: z.number(), + }), + }), + run: async (payload, io, ctx) => { + await io.wait("sleeping", payload.delay); + + await io.runTask("init", { name: "init" }, async () => { + console.log("init function ran", payload.userId); + }); + + await io.runTask("failable", { name: "task-1", retry: { limit: 3 } }, async (task) => { + if (task.attempts > 2) { + console.log("task succeeded"); + return { + ok: true, + }; + } + console.log("task failed"); + throw new Error(`Task failed on ${task.attempts} attempt(s)`); + }); + + await io.runTask( + "log", + { + name: "log", + }, + async () => { + console.log("hello from the job", payload.userId); + } + ); + }, +}); + createExpressServer(client); diff --git a/packages/trigger-sdk/src/io.ts b/packages/trigger-sdk/src/io.ts index cf7769573..3db37c7f2 100644 --- a/packages/trigger-sdk/src/io.ts +++ b/packages/trigger-sdk/src/io.ts @@ -504,8 +504,8 @@ export class IO { const cachedTask = this._cachedTasks.get(idempotencyKey); - if (cachedTask) { - this._logger.debug("Using cached task", { + if (cachedTask && cachedTask.status === "COMPLETED") { + this._logger.debug("Using completed cached task", { idempotencyKey, cachedTask, });