cf13fbdf32
* Add triggerAndWait().unwrap() to more easily get at the output or throw the subtask error * Add taskId and runId to SubtaskUnwrapError * WIP docs update beta -> latest * trigger.dev init now adds @trigger.dev/build to devDependencies * How it works doc * Restructure some docs and update the cli commands * Config file docs, plus aptGet and ffmpeg extensions * Update to latest from beta docs * Add runtime to templates * Add --runtime option to the init CLI command * A bunch more doc updates after feedback * Document triggerAndWait with unwrap and result types * beta -> latest in the webapp * CLI update check no longer references beta * Add major release * Leave changeset beta, back to normal package release * Fixed default dirs option in init command * exclude windows-yarn variation of cli e2e tests because it’s buggy * Remove cache to try and fix yarn e2e test workflow errors
278 lines
8.1 KiB
Plaintext
278 lines
8.1 KiB
Plaintext
---
|
||
title: "Tasks: Overview"
|
||
sidebarTitle: "Overview"
|
||
description: "Tasks are functions that can run for a long time and provide strong resilience to failure."
|
||
---
|
||
|
||
There are different types of tasks including regular tasks and [scheduled tasks](/tasks/scheduled).
|
||
|
||
## Hello world task and how to trigger it
|
||
|
||
Here's an incredibly simple task:
|
||
|
||
```ts /trigger/hello-world.ts
|
||
import { task } from "@trigger.dev/sdk/v3";
|
||
|
||
//1. You need to export each task
|
||
export const helloWorld = task({
|
||
//2. Use a unique id for each task
|
||
id: "hello-world",
|
||
//3. The run function is the main function of the task
|
||
run: async (payload: { message: string }) => {
|
||
//4. You can write code that runs for a long time here, there are no timeouts
|
||
console.log(payload.message);
|
||
},
|
||
});
|
||
```
|
||
|
||
You can trigger this in two ways:
|
||
|
||
1. From the dashboard [using the "Test" feature](/run-tests).
|
||
2. Trigger it from your backend code. See the [full triggering guide here](/triggering).
|
||
|
||
Here's how to trigger a single run from elsewhere in your code:
|
||
|
||
```ts Your backend code
|
||
import { helloWorldTask } from "./trigger/hello-world";
|
||
|
||
async function triggerHelloWorld() {
|
||
//This triggers the task and returns a handle
|
||
const handle = await helloWorld.trigger({ message: "Hello world!" });
|
||
|
||
//You can use the handle to check the status of the task, cancel and retry it.
|
||
console.log("Task is running with handle", handle.id);
|
||
}
|
||
```
|
||
|
||
You can also [trigger a task from another task](/triggering), and wait for the result.
|
||
|
||
## Defining a `task`
|
||
|
||
The task function takes an object with the following fields.
|
||
|
||
### The `id` field
|
||
|
||
This is used to identify your task so it can be triggered, managed, and you can view runs in the dashboard. This must be unique in your project – we recommend making it descriptive and unique.
|
||
|
||
### The `run` function
|
||
|
||
Your custom code inside `run()` will be executed when your task is triggered. It’s an async function that has two arguments:
|
||
|
||
1. The run payload - the data that you pass to the task when you trigger it.
|
||
2. An object with `ctx` about the run (Context), and any output from the optional `init` function that runs before every run attempt.
|
||
|
||
Anything you return from the `run` function will be the result of the task. Data you return must be JSON serializable: strings, numbers, booleans, arrays, objects, and null.
|
||
|
||
### `retry` options
|
||
|
||
A task is retried if an error is thrown, by default we retry 3 times.
|
||
|
||
You can set the number of retries and the delay between retries in the `retry` field:
|
||
|
||
```ts /trigger/retry.ts
|
||
export const taskWithRetries = task({
|
||
id: "task-with-retries",
|
||
retry: {
|
||
maxAttempts: 10,
|
||
factor: 1.8,
|
||
minTimeoutInMs: 500,
|
||
maxTimeoutInMs: 30_000,
|
||
randomize: false,
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
For more information read [the retrying guide](/errors-retrying).
|
||
|
||
It's also worth mentioning that you can [retry a block of code](/errors-retrying) inside your tasks as well.
|
||
|
||
### `queue` options
|
||
|
||
Queues allow you to control the concurrency of your tasks. This allows you to have one-at-a-time execution and parallel executions. There are also more advanced techniques like having different concurrencies for different sets of your users. For more information read [the concurrency & queues guide](/queue-concurrency).
|
||
|
||
```ts /trigger/one-at-a-time.ts
|
||
export const oneAtATime = task({
|
||
id: "one-at-a-time",
|
||
queue: {
|
||
concurrencyLimit: 1,
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
### `machine` options
|
||
|
||
Some tasks require more vCPUs or GBs of RAM. You can specify these requirements in the `machine` field. For more information read [the machines guide](/machines).
|
||
|
||
```ts /trigger/heavy-task.ts
|
||
export const heavyTask = task({
|
||
id: "heavy-task",
|
||
machine: {
|
||
preset: "large-1x", // 4 vCPU, 8 GB RAM
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
## Lifecycle functions
|
||
|
||

|
||
|
||
### `init` function
|
||
|
||
This function is called before a run attempt:
|
||
|
||
```ts /trigger/init.ts
|
||
export const taskWithInit = task({
|
||
id: "task-with-init",
|
||
init: async (payload, { ctx }) => {
|
||
//...
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
You can also return data from the `init` function that will be available in the params of the `run`, `cleanup`, `onSuccess`, and `onFailure` functions.
|
||
|
||
```ts /trigger/init-return.ts
|
||
export const taskWithInitReturn = task({
|
||
id: "task-with-init-return",
|
||
init: async (payload, { ctx }) => {
|
||
return { someData: "someValue" };
|
||
},
|
||
run: async (payload: any, { ctx, init }) => {
|
||
console.log(init.someData); // "someValue"
|
||
},
|
||
});
|
||
```
|
||
|
||
### `cleanup` function
|
||
|
||
This function is called after the `run` function is executed, regardless of whether the run was successful or not. It's useful for cleaning up resources, logging, or other side effects.
|
||
|
||
```ts /trigger/cleanup.ts
|
||
export const taskWithCleanup = task({
|
||
id: "task-with-cleanup",
|
||
cleanup: async (payload, { ctx }) => {
|
||
//...
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
### `middleware` function
|
||
|
||
This function is called before the `run` function, it allows you to wrap the run function with custom code.
|
||
|
||
### `onStart` function
|
||
|
||
When a task run starts, the `onStart` function is called. It's useful for sending notifications, logging, and other side effects. This function will only be called one per run (not per retry). If you want to run code before each retry, use the `init` function.
|
||
|
||
```ts /trigger/on-start.ts
|
||
export const taskWithOnStart = task({
|
||
id: "task-with-on-start",
|
||
onStart: async (payload, { ctx }) => {
|
||
//...
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
You can also define an `onStart` function in your `trigger.config.ts` file to get notified when any task starts.
|
||
|
||
```ts trigger.config.ts
|
||
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
|
||
|
||
export const config: TriggerConfig = {
|
||
onStart: async (payload, { ctx }) => {
|
||
console.log("Task started", ctx.task.id);
|
||
},
|
||
};
|
||
```
|
||
|
||
### `onSuccess` function
|
||
|
||
When a task run succeeds, the `onSuccess` function is called. It's useful for sending notifications, logging, syncing state to your database, or other side effects.
|
||
|
||
```ts /trigger/on-success.ts
|
||
export const taskWithOnSuccess = task({
|
||
id: "task-with-on-success",
|
||
onSuccess: async (payload, output, { ctx }) => {
|
||
//...
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
You can also define an `onSuccess` function in your `trigger.config.ts` file to get notified when any task succeeds.
|
||
|
||
```ts trigger.config.ts
|
||
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
|
||
|
||
export const config: TriggerConfig = {
|
||
onSuccess: async (payload, output, { ctx }) => {
|
||
console.log("Task succeeded", ctx.task.id);
|
||
},
|
||
};
|
||
```
|
||
|
||
### `onFailure` function
|
||
|
||
When a task run fails, the `onFailure` function is called. It's useful for sending notifications, logging, or other side effects. It will only be executed once the task run has exhausted all its retries.
|
||
|
||
```ts /trigger/on-failure.ts
|
||
export const taskWithOnFailure = task({
|
||
id: "task-with-on-failure",
|
||
onFailure: async (payload, error, { ctx }) => {
|
||
//...
|
||
},
|
||
run: async (payload: any, { ctx }) => {
|
||
//...
|
||
},
|
||
});
|
||
```
|
||
|
||
You can also define an `onFailure` function in your `trigger.config.ts` file to get notified when any task fails.
|
||
|
||
```ts trigger.config.ts
|
||
import type { TriggerConfig } from "@trigger.dev/sdk/v3";
|
||
|
||
export const config: TriggerConfig = {
|
||
onFailure: async (payload, error, { ctx }) => {
|
||
console.log("Task failed", ctx.task.id);
|
||
},
|
||
};
|
||
```
|
||
|
||
### `handleError` functions
|
||
|
||
You can define a function that will be called when an error is thrown in the `run` function, that allows you to control how the error is handled and whether the task should be retried.
|
||
|
||
Read more about `handleError` in our [Errors and Retrying guide](/errors-retrying).
|
||
|
||
## Next steps
|
||
|
||
<CardGroup>
|
||
<Card title="Triggering" icon="bolt" href="/triggering">
|
||
Learn how to trigger your tasks from your code.
|
||
</Card>
|
||
<Card title="Writing tasks" icon="wand-magic-sparkles" href="/writing-tasks-introduction">
|
||
Tasks are the core of Trigger.dev. Learn how to write them.
|
||
</Card>
|
||
</CardGroup>
|