-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Batch Trigger upgrades #1502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Batch Trigger upgrades #1502
Changes from 1 commit
7ec44c2
e9f2f8c
5ee6b8e
b4ed220
bd14761
6097160
4aa5845
d69abd1
a664859
a0dfd2d
daec8f4
aa82f8d
976b275
1674d33
e8cfe88
b0c3c41
4b181fa
fd18784
26980f0
492fb79
0060a64
f1919b1
1b34daf
2ebc4e5
658f400
ff65310
5f5cbe2
e60b75b
eac6aa7
4b2932a
4070c6a
f97d55e
78e3a56
f95569a
b7599ed
99a3137
681e75a
bc07b52
b822915
4c5fd2a
fc821ad
d5c1bda
69f3dca
153af67
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ngle batch
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| --- | ||
| "@trigger.dev/sdk": patch | ||
| "trigger.dev": patch | ||
| "@trigger.dev/core": patch | ||
| --- | ||
|
|
||
| Added new batch.trigger and batch.triggerByTask methods that allows triggering multiple different tasks in a single batch: | ||
|
|
||
| ```ts | ||
| import { batch } from '@trigger.dev/sdk/v3'; | ||
| import type { myTask1, myTask2 } from './trigger/tasks'; | ||
|
|
||
| // Somewhere in your backend code | ||
| const response = await batch.trigger<typeof myTask1 | typeof myTask2>([ | ||
| { id: 'task1', payload: { foo: 'bar' } }, | ||
| { id: 'task2', payload: { baz: 'qux' } }, | ||
| ]); | ||
|
|
||
| for (const run of response.runs) { | ||
| if (run.ok) { | ||
| console.log(run.output); | ||
| } else { | ||
| console.error(run.error); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Or if you are inside of a task, you can use `triggerByTask`: | ||
|
|
||
| ```ts | ||
| import { batch, task, runs } from '@trigger.dev/sdk/v3'; | ||
|
|
||
| export const myParentTask = task({ | ||
| id: 'myParentTask', | ||
| run: async () => { | ||
| const response = await batch.triggerByTask([ | ||
| { task: myTask1, payload: { foo: 'bar' } }, | ||
| { task: myTask2, payload: { baz: 'qux' } }, | ||
| ]); | ||
|
|
||
| const run1 = await runs.retrieve(response.runs[0]); | ||
| console.log(run1.output) // typed as { foo: string } | ||
|
|
||
| const run2 = await runs.retrieve(response.runs[1]); | ||
| console.log(run2.output) // typed as { baz: string } | ||
|
|
||
ericallam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const response2 = await batch.triggerByTaskAndWait([ | ||
| { task: myTask1, payload: { foo: 'bar' } }, | ||
| { task: myTask2, payload: { baz: 'qux' } }, | ||
| ]); | ||
|
|
||
| if (response2.runs[0].ok) { | ||
| console.log(response2.runs[0].output) // typed as { foo: string } | ||
| } | ||
|
|
||
| if (response2.runs[1].ok) { | ||
| console.log(response2.runs[1].output) // typed as { baz: string } | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| export const myTask1 = task({ | ||
| id: 'myTask1', | ||
| run: async () => { | ||
| return { | ||
| foo: 'bar' | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| export const myTask2 = task({ | ||
| id: 'myTask2', | ||
| run: async () => { | ||
| return { | ||
| baz: 'qux' | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1038,13 +1038,15 @@ class SharedQueueTasks { | |
| id: attempt.taskRun.friendlyId, | ||
| output: attempt.output ?? undefined, | ||
| outputType: attempt.outputType, | ||
| taskIdentifier: attempt.taskRun.taskIdentifier, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure In both instances, Modify the code to safely access - taskIdentifier: attempt.taskRun.taskIdentifier,
+ taskIdentifier: attempt.taskRun?.taskIdentifier,Also applies to: 1049-1049 |
||
| }; | ||
| return success; | ||
| } else { | ||
| const failure: TaskRunFailedExecutionResult = { | ||
| ok, | ||
| id: attempt.taskRun.friendlyId, | ||
| error: attempt.error as TaskRunError, | ||
| taskIdentifier: attempt.taskRun.taskIdentifier, | ||
| }; | ||
| return failure; | ||
| } | ||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,18 +49,24 @@ export class SubtaskUnwrapError extends Error { | |
| } | ||
| } | ||
|
|
||
| export class TaskRunPromise<T> extends Promise<TaskRunResult<T>> { | ||
| export class TaskRunPromise<TIdentifier extends string, TOutput> extends Promise< | ||
| TaskRunResult<TIdentifier, TOutput> | ||
| > { | ||
| constructor( | ||
| executor: ( | ||
| resolve: (value: TaskRunResult<T> | PromiseLike<TaskRunResult<T>>) => void, | ||
| resolve: ( | ||
| value: | ||
| | TaskRunResult<TIdentifier, TOutput> | ||
| | PromiseLike<TaskRunResult<TIdentifier, TOutput>> | ||
| ) => void, | ||
| reject: (reason?: any) => void | ||
| ) => void, | ||
| private readonly taskId: string | ||
| private readonly taskId: TIdentifier | ||
| ) { | ||
| super(executor); | ||
| } | ||
|
|
||
| unwrap(): Promise<T> { | ||
| unwrap(): Promise<TOutput> { | ||
| return this.then((result) => { | ||
| if (result.ok) { | ||
| return result.output; | ||
|
|
@@ -415,38 +421,101 @@ export type RunHandleTaskIdentifier<TRunHandle> = TRunHandle extends RunHandle< | |
| ? TTaskIdentifier | ||
| : never; | ||
|
|
||
| export type TaskRunResult<TOutput = any> = | ||
| export type TaskRunResult<TIdentifier extends string, TOutput = any> = | ||
| | { | ||
| ok: true; | ||
| id: string; | ||
| taskIdentifier: string; | ||
| taskIdentifier: TIdentifier; | ||
| output: TOutput; | ||
| } | ||
| | { | ||
| ok: false; | ||
| id: string; | ||
| taskIdentifier: string; | ||
| taskIdentifier: TIdentifier; | ||
| error: unknown; | ||
| }; | ||
|
|
||
| export type BatchResult<TOutput = any> = { | ||
| export type AnyTaskRunResult = TaskRunResult<string, any>; | ||
|
|
||
| export type TaskRunResultFromTask<TTask extends AnyTask> = TTask extends Task< | ||
| infer TIdentifier, | ||
| any, | ||
| infer TOutput | ||
| > | ||
| ? TaskRunResult<TIdentifier, TOutput> | ||
| : never; | ||
|
|
||
| export type BatchResult<TIdentifier extends string, TOutput = any> = { | ||
| id: string; | ||
| runs: TaskRunResult<TIdentifier, TOutput>[]; | ||
| }; | ||
|
|
||
| export type BatchByIdResult<TTask extends AnyTask> = { | ||
| id: string; | ||
| runs: Array<TaskRunResultFromTask<TTask>>; | ||
| }; | ||
|
|
||
| export type BatchByTaskResult<TTasks extends readonly AnyTask[]> = { | ||
| id: string; | ||
| runs: TaskRunResult<TOutput>[]; | ||
| runs: { | ||
| [K in keyof TTasks]: TaskRunResultFromTask<TTasks[K]>; | ||
| }; | ||
| }; | ||
|
|
||
| /** | ||
| * A BatchRunHandle can be used to retrieve the runs of a batch trigger in a typesafe manner. | ||
| */ | ||
| // export type BatchTasksRunHandle<TTasks extends readonly AnyTask[]> = BrandedRun< | ||
| // { | ||
| // batchId: string; | ||
| // isCached: boolean; | ||
| // idempotencyKey?: string; | ||
| // runs: { | ||
| // [K in keyof TTasks]: BatchedRunHandle< | ||
| // TaskIdentifier<TTasks[K]>, | ||
| // TaskPayload<TTasks[K]>, | ||
| // TaskOutput<TTasks[K]> | ||
| // >; | ||
| // }; | ||
| // publicAccessToken: string; | ||
| // }, | ||
| // any, | ||
| // any | ||
| // >; | ||
|
|
||
| export type BatchTasksResult<TTasks extends readonly AnyTask[]> = BatchTasksRunHandle<TTasks>; | ||
|
|
||
| export type BatchItem<TInput> = { payload: TInput; options?: TriggerOptions }; | ||
|
|
||
| export type BatchTriggerAndWaitItem<TInput> = { | ||
| payload: TInput; | ||
| options?: TriggerAndWaitOptions; | ||
| }; | ||
|
|
||
| export type BatchAllItem<TRunTypes extends AnyRunTypes> = { | ||
| task: TRunTypes["taskIdentifier"]; | ||
| export type BatchByIdItem<TRunTypes extends AnyRunTypes> = { | ||
| id: TRunTypes["taskIdentifier"]; | ||
| payload: TRunTypes["payload"]; | ||
| options?: TriggerOptions; | ||
| }; | ||
|
|
||
| export type BatchByIdAndWaitItem<TRunTypes extends AnyRunTypes> = { | ||
| id: TRunTypes["taskIdentifier"]; | ||
| payload: TRunTypes["payload"]; | ||
| options?: TriggerAndWaitOptions; | ||
| }; | ||
|
|
||
| export type BatchByTaskItem<TTask extends AnyTask> = { | ||
| task: TTask; | ||
| payload: TaskPayload<TTask>; | ||
| options?: TriggerOptions; | ||
| }; | ||
|
|
||
| export type BatchByTaskAndWaitItem<TTask extends AnyTask> = { | ||
| task: TTask; | ||
| payload: TaskPayload<TTask>; | ||
| options?: TriggerAndWaitOptions; | ||
| }; | ||
|
|
||
| export interface Task<TIdentifier extends string, TInput = void, TOutput = any> { | ||
| /** | ||
| * The id of the task. | ||
|
|
@@ -497,7 +566,10 @@ export interface Task<TIdentifier extends string, TInput = void, TOutput = any> | |
| * } | ||
| * ``` | ||
| */ | ||
| triggerAndWait: (payload: TInput, options?: TriggerAndWaitOptions) => TaskRunPromise<TOutput>; | ||
| triggerAndWait: ( | ||
| payload: TInput, | ||
| options?: TriggerAndWaitOptions | ||
| ) => TaskRunPromise<TIdentifier, TOutput>; | ||
|
Comment on lines
+569
to
+572
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Breaking change: Removal of idempotencyKey from triggerAndWait options impacts existing code The verification reveals this is indeed a breaking change:
This change will break existing code that relies on idempotency control in 🔗 Analysis chainVerify impact of removing idempotencyKey from triggerAndWait options. The removal of 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Find usages of triggerAndWait with idempotencyKey to assess impact
# Search for triggerAndWait calls with idempotencyKey
rg -A 3 'triggerAndWait.*idempotencyKey'
# Search for batchTriggerAndWait calls with idempotencyKey
rg -A 3 'batchTriggerAndWait.*idempotencyKey'
Length of output: 4171 Script: #!/bin/bash
# Let's check the git history to see if this is a new or existing feature
git log -p packages/core/src/v3/types/tasks.ts | grep -A 5 -B 5 'TriggerAndWaitOptions'
# Also check the current definition of TriggerAndWaitOptions
rg -A 10 'export.*TriggerAndWaitOptions' packages/core/src/v3/types/tasks.ts
# And check for any interface that extends TriggerAndWaitOptions
ast-grep --pattern 'interface $_ extends TriggerAndWaitOptions'
Length of output: 573 Script: #!/bin/bash
# Let's check the definition of TriggerOptions to understand what's being omitted
rg -A 10 'export.*TriggerOptions\s*=' packages/core/src/v3/types/tasks.ts
# Also check if there are any recent changes to TriggerAndWaitOptions in the changelog
rg -B 5 'TriggerAndWaitOptions' packages/core/CHANGELOG.md
Length of output: 979 |
||
|
|
||
| /** | ||
| * Batch trigger multiple task runs with the given payloads, and wait for the results. Returns the results of the task runs. | ||
|
|
@@ -521,7 +593,7 @@ export interface Task<TIdentifier extends string, TInput = void, TOutput = any> | |
| */ | ||
| batchTriggerAndWait: ( | ||
| items: Array<BatchTriggerAndWaitItem<TInput>> | ||
| ) => Promise<BatchResult<TOutput>>; | ||
| ) => Promise<BatchResult<TIdentifier, TOutput>>; | ||
| } | ||
|
|
||
| export interface TaskWithSchema< | ||
|
|
@@ -758,3 +830,27 @@ export type RunHandleFromTypes<TRunTypes extends AnyRunTypes> = RunHandle< | |
| export type BatchRunHandleFromTypes<TRunTypes extends AnyRunTypes> = TRunTypes extends AnyRunTypes | ||
| ? BatchRunHandle<TRunTypes["taskIdentifier"], TRunTypes["payload"], TRunTypes["output"]> | ||
| : never; | ||
|
|
||
| /** | ||
| * A BatchRunHandle can be used to retrieve the runs of a batch trigger in a typesafe manner. | ||
| */ | ||
| export type BatchTasksRunHandle<TTasks extends readonly AnyTask[]> = BrandedRun< | ||
| { | ||
| batchId: string; | ||
| isCached: boolean; | ||
| idempotencyKey?: string; | ||
| runs: { | ||
| [K in keyof TTasks]: BatchedRunHandle< | ||
| TaskIdentifier<TTasks[K]>, | ||
| TaskPayload<TTasks[K]>, | ||
| TaskOutput<TTasks[K]> | ||
| >; | ||
| }; | ||
| publicAccessToken: string; | ||
| }, | ||
| any, | ||
| any | ||
| >; | ||
|
|
||
| export type BatchTasksRunHandleFromTypes<TTasks extends readonly AnyTask[]> = | ||
| BatchTasksRunHandle<TTasks>; | ||
Uh oh!
There was an error while loading. Please reload this page.