Files
triggerdotdev--trigger.dev/docs/v3/migration-defer.mdx
T
2024-04-19 18:30:58 +01:00

291 lines
8.0 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Migrating from Defer.run"
description: "A guide to migrating from Defer to Trigger.dev v3"
---
First of all, you should use the [Trigger.dev v3 Developer Preview](https://trigger.dev/blog/v3-developer-preview-launch/), not version 2. Version 2 is not a good choice if you're coming from Defer as the execution model is very different. [Let us know](https://) if you need v3 access.
This guide highlights the differences and should help you migrate your project.
## Features coming very soon
Here are some features you might be using in Defer that are coming this month to v3:
- Triggering a task with a delay (like `assignOptions` delay in Defer) will be available soon there is [an alternative](#delay) you can use for now.
You can view the full feature matrix [here](/v3/feature-matrix).
## Differences
#### Local development
In Defer you run your tasks locally using `npm run dev` (or other package manager). This is simple but it means dev behaved differently from production for your background tasks.
With Trigger.dev you need to use our CLI to run a local server that behaves like the deployed production environment. It also means you will see your runs in the dashboard.
#### Multiple tasks in a single file
In Defer you needed to use a default export in a file inside your `/defer` directory.
```ts /defer/longRunningTask.ts
import { defer } from "@defer/client";
async function longRunningTask() {
// runs a fake task for 30s
await performLongRunningTask();
}
export default defer(longRunningTask);
```
In Trigger.dev **you use named exports** so you can have multiple tasks in a single file.
```ts /trigger/someTasks.ts
export const longRunningTask = task({
id: "longRunningTask",
run: async (payload: any) => {
//...do stuff
},
});
export const otherTask = task({
id: "otherTask",
run: async (payload: any) => {
//...do different stuff
},
});
```
#### Triggering your tasks
In Defer, you wrapped your existing function in `defer()`. Then for simple cases you could just call the function. In other cases, like when you wanted to have a delay you needed to use `assignOptions` to create a new function.
```ts /app/actions/actions.ts
"use server";
import longRunningTask from "@/defer/longRunningTask";
export async function runLongRunningTask() {
return await longRunningTask();
}
```
In Trigger.dev your logic goes in the `run` function of a task. You can then `trigger` and `batchTrigger` that task, with a payload as the first argument.
```ts /app/actions/actions.ts
"use server";
import { longRunningTask } from "@/trigger/someTasks";
export async function runLongRunningTask() {
return await longRunningTask.trigger({ foo: "bar" });
}
```
#### `wait`
In Trigger.dev you can use the [wait](/v3/wait) functions to freeze execution of your code until a later date (it can be months later). You won't pay while it's frozen and the state is restored exactly when it wakes (using a technology called CRIU).
```ts
//In Defer you could use "sleep" but that would keep your function running.
await sleep(1000 * 60 * 5); // 5 minutes but you'd pay for it.
//In Trigger.dev you can use wait. We freeze execution if it's more than 30s
await wait.for({ seconds: 5 });
await wait.for({ minutes: 10 });
await wait.for({ hours: 1 });
await wait.for({ days: 1 });
await wait.for({ weeks: 1 });
await wait.for({ months: 1 });
await wait.for({ years: 1 });
//you can wait for a date too
await wait.until({ date: aFutureDate });
```
#### delay the start of a run
In Defer you can do this:
```ts
const delayedRun = assignOptions(someTask, { delay: "10s" });
await delayedRun();
```
There will be a nice way to do this soon when you call `trigger()` but for now you can use `wait` to get the same behavior:
```ts
export const helloWorld = task({
id: "hello-world",
run: async (payload: { delayUntil?: string; delayForSeconds?: number }) => {
if (payload.delayUntil) {
await wait.until({ date: new Date(payload.delayUntil) });
}
if (payload.delayForSeconds) {
await wait.for({ seconds: payload.delayForSeconds });
}
//do stuff
},
});
```
## How to migrate
### 1. Get Trigger.dev working in your project
<Steps>
<Step title="Create an organization on Trigger.dev">
1. Go to the [Trigger.dev Cloud](https://cloud.trigger.dev)
2. Create an account
3. Create an organization with a project (this will be a version 2 project)
4. [DM us on Discord](https://trigger.dev/discord) or [fill in this form](https://trigger.dev/v3-early-access) and mention Defer in the company name.
We will grant you v3 access.
</Step>
<Step title="Create a v3 project">
1. Go to the Projects page
![Click the Projects page](/images/v3/sidemenu-projects.png)
2. Click "Create a new project"
![Click "Create a new project"](/images/v3/projects-new-button.png)
3. Make sure you select "Version 3" from the dropdown!
![Select "Version 3"](/images/v3/projects-new-v3.png)
<Warning>
If you don't see a dropdown then you don't have v3 access. [Fill in this
form](https://trigger.dev/v3-early-access) and mention Defer in the company name.
</Warning>
</Step>
<Snippet file="v3/step-cli-init.mdx" />
<Snippet file="v3/step-cli-dev.mdx" />
<Snippet file="v3/step-run-test.mdx" />
<Snippet file="v3/step-view-run.mdx" />
</Steps>
### 2. Migrate your Defer functions to Trigger.dev tasks
#### Example 1: Simple function
In Defer you might have a function like this.
<CodeGroup>
```ts /defer/longRunningTask.ts
import { performLongRunningTask } from "@/utils/performLongRunningTask";
import { defer } from "@defer/client";
async function longRunningTask() {
// runs a fake task for 30s
await performLongRunningTask();
}
export default defer(longRunningTask, {
concurrency: 2, // want maximum 2 executions of this function in parallel
retry: 5, // adding retry to recover from potential network issues or rate limiting
});
```
```ts /app/actions/actions.ts
"use server";
import longRunningTask from "@/defer/longRunningTask";
export async function runLongRunningTask() {
return await longRunningTask();
}
```
</CodeGroup>
In Trigger.dev it looks like this:
<CodeGroup>
```ts /trigger/someTasks.ts
import { performLongRunningTask } from "@/utils/performLongRunningTask";
import { task } from "@trigger.dev/sdk/v3";
//named export
export const longRunningTask = task({
//a unique and stable ID so you can refactor the function name
id: "long-running-task",
queue: {
concurrencyLimit: 2, // want maximum 2 executions of this function in parallel
},
retry: {
maxAttempts: 5, // adding retry to recover from potential network issues or rate limiting
},
run: async (payload: any) => {
// runs a fake task for 30s
await performLongRunningTask();
},
});
```
```ts /app/actions/actions.ts
"use server";
import { longRunningTask } from "@/trigger/longRunningTask";
export async function runLongRunningTask() {
return await longRunningTask.trigger({ foo: "bar" });
}
```
</CodeGroup>
<Warning>
You need to set your `TRIGGER_SECRET_KEY` environment variable in your `.env` or `.env.local` file
to trigger tasks from your code. See the [API keys page](/v3/apikeys) for more information.
</Warning>
#### Example 2: A CRON task
We call these [scheduled tasks](/v3/tasks-scheduled) in Trigger.dev.
In Defer you might have a function like this:
```ts
import { defer } from "@defer/client";
async function sendMondayNewletter() {
// business logic here
}
export default defer.cron(sendMondayNewletter, "0 0 * * 1");
```
In Trigger.dev the task looks like this:
```ts
import { schedules } from "@trigger.dev/sdk/v3";
//this task will run when any of the attached schedules trigger
export const sendMondayNewletter = schedules.task({
id: "send-monday-newsletter",
run: async (payload) => {
// business logic here
},
});
```
Then you need to attach a schedule to the task, either using the dashboard or in your code. You can attach unlimited schedules to a task.
<Card title="Attaching schedules" icon="clock" href="/v3/tasks-scheduled">
How to attach a schedule to a task
</Card>