72f3a4b128
* v3 subscription endpoints * Use pnpm linked billing package during development * Moved v2 billing components into a subfolder * Select plan using the real data * Improved v3 plan display * Use new api response that doesn’t require a Stripe call * Free flow is working * Added GitHub modal and verified badge * Deleted old request v3 access component/route * Allow setting classes on the Tooltip button * Paid plans working * Redirect from select plan if you’ve got v3 enabled * Loading state improvements * New admin API endpoint to set concurrency across multiple environments * When projects are created, conditionally create staging based on the plan * New billing page working with side menu and stripe portal * Layout, formatting and some plan state improvements/fixes * Don’t show the period if you’re on the free plan * Temporary upgrade callout * Refactored the platform code so it’s easier to call and doesn’t require a isManagedCloud check * Send taskIdentifier to OpenMeter * Side menu * Upgrade prompts * More improvements to the app-wide usage indicators * Early work on usage graphs * Added the usage bar for v3 * Moved code to presenter and now using defer * Added the tasks table to usage * Improved the v3 usage bar if theres’ no usage on a paid plan * If no run data, still render a graph * Usage page errors when defered loading fails * Don’t show the public API key for v3, they’re not used and probably never will be * Improved the upgrade callout and API keys page layout * Only show the “reveal all” toggle if you have environment variables in the table * Replaced Upgrade callout with a more generic InfoPanel component * better panel width * Show conditional upgrade prompts based on plan and number of schedules used * Removed duplicate class * Wider blank state panels for the scheduled page * Wider info panel for the env var page * Blank state now using the info panel * Platform alerts prompt now using the InfoPanel * Deploy blank state uses InfoPanel * Github verified badge padding adjustment * Improved the layout of the page, some style tweaks, organized imports * Better default tooltip style * could be undefined fix * text fix + style updates * Changed the billing icon in the side menu * Billing page layout and style improvements * plan tooltips don’t use dark variant * Don’t highlight the plan on the billing page * Tooltip underlines stand out more * Fixed padding in the PageTitle * Tooltips use the correct cursor * Improved the plan banner on the billing page * Fixed Header1 inconsistent font weight * Fixed issue where input field focus states were being clipped * Fixed large button not having large text size * Added a link to the Get in touch copy and improved the connect to GitHub modal * Select plan page uses the MainCenteredContainer * Better logging from the Loops endpoint because this error finally got hit * Move the ingestion of compute to the platform * Reporting usage of invocations moved to the platform * Get the entitlement before triggering a non-dev task * Contact us enterprise plan button opens the feedback form * Removed Github discussions link from the Feedback panel * Swapped billing icon for credit card * Show a Unlock staging panel on the env var page * Updated staging environment colour * Show a prompt to upgrade to get staging in the new env var modal * Improved the edit env var modal * Implement ability to disable org concurrency * Use common logic for the plans * Use the billing server to get the schedule limits * Some schedules page fixes * More convenient way of getting a limit * Use the new schedule limit * Team member limiting * Made the limit visible on the team page * Limit alerts * Added an index for TaskRun.scheduleId * Remove console.log on schedules page * Added durations to the run table * Tabular numbers * Improved the usage page formatting * Only admins see the compute column on the run table * Include the base cost on the usage stats * Moved the status to the sidebar * Optional table header tooltip * Allow InfoIconTooltips to have customizable content styles * Added a tooltip to the duration header, changed no test to a dash * Removed all references to signing up to v3 from the docs * Switched @trigger.dev/billing to @trigger.dev/platform * Passing up the variant for the InfoIconTooltip * table tooltip max-width fixed * Switch to the published @trigger.dev/platform 1.0.11 * v2 usage page title changed to include “v2" * code theme has a transparent background so it works on any background * duration columns now grouped together nicely at wide screen size * Last duration column fills the width properly * Fix for the per run price being in cents not dollars * Show the total cost with 8 decimal places * Show 8 decimal places in the usage graph tooltip * Moved the UpgradePrompt to the v3 folder * Prepare to use Shadcns chart helpers * Much nicer chart * Small tweaks to the graph * Fix run table col spans for empty/loading messages * We don’t need isManagedCloud in createProject * Hide v3 usage/billing pages if there aren’t v3 projects in your org * Removed unused tooltipStyle * Usage bar now says “Included usage” instead of “Tier limit” if you’re paying * Get the plan/usage data in parallel * The usage page now has a month dropdown and all data is for that calendar month * Ensure the passed date is the 1st of the month * Use the machine presets from the platform package --------- Co-authored-by: James Ritchie <james@jamesritchie.co.uk> Co-authored-by: Eric Allam <eallam@icloud.com>
281 lines
7.6 KiB
Plaintext
281 lines
7.6 KiB
Plaintext
---
|
||
title: "Migrating from Defer.run"
|
||
description: "A guide to migrating from Defer to Trigger.dev v3"
|
||
---
|
||
|
||
This guide highlights the differences between Defer and Trigger.dev 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
|
||

|
||
|
||
2. Click "Create a new project"
|
||

|
||
|
||
3. If the "Project version" dropdown is visible, make sure you select "Version 3"!
|
||

|
||
|
||
</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>
|