187 lines
5.7 KiB
Plaintext
187 lines
5.7 KiB
Plaintext
---
|
|
title: "Upgrading from v2"
|
|
description: "How to upgrade v2 jobs to v3 tasks, and how to use them together."
|
|
---
|
|
|
|
## v3 feature matrix
|
|
|
|
As v3 is in Developer Preview there are some features that are not yet available. Take a look at the [Feature matrix](/v3/feature-matrix) to check what is currently available.
|
|
|
|
## Changes from v2 to v3
|
|
|
|
The main difference is that things in v3 are far simpler. That's because in v3 your code is deployed to our servers (unless you self-host) which are long-running.
|
|
|
|
1. No timeouts.
|
|
2. No `io.runTask()` (and no `cacheKeys`).
|
|
3. Just use official SDKs, not integrations.
|
|
4. `task`s are the new primitive, not `job`s.
|
|
|
|
## OpenAI example comparison
|
|
|
|
This is a (very contrived) example that does a long OpenAI API call (>10s), stores the result in a database, waits for 5 mins, and then returns the result.
|
|
|
|
### v2
|
|
|
|
First, the old v2 code, which uses the OpenAI integration. Comments inline:
|
|
|
|
```ts v2 OpenAI task
|
|
import { client } from "~/trigger";
|
|
import { eventTrigger } from "@trigger.dev/sdk";
|
|
|
|
//1. A Trigger.dev integration for OpenAI
|
|
import { OpenAI } from "@trigger.dev/openai";
|
|
const openai = new OpenAI({
|
|
id: "openai",
|
|
apiKey: process.env["OPENAI_API_KEY"]!,
|
|
});
|
|
|
|
//2. Use the client to define a "Job"
|
|
client.defineJob({
|
|
id: "openai-tasks",
|
|
name: "OpenAI Tasks",
|
|
version: "0.0.1",
|
|
trigger: eventTrigger({
|
|
name: "openai.tasks",
|
|
schema: z.object({
|
|
prompt: z.string(),
|
|
}),
|
|
}),
|
|
//3. integrations are added and come through to `io` in the run fn
|
|
integrations: {
|
|
openai,
|
|
},
|
|
run: async (payload, io, ctx) => {
|
|
//4. You use `io` to get the integration
|
|
//5. Also note that "backgroundCreate" was needed for OpenAI
|
|
// to do work that lasted longer than your serverless timeout
|
|
const chatCompletion = await io.openai.chat.completions.backgroundCreate(
|
|
//6. You needed to add "cacheKeys" to any "task"
|
|
"background-chat-completion",
|
|
{
|
|
messages: [{ role: "user", content: payload.prompt }],
|
|
model: "gpt-3.5-turbo",
|
|
}
|
|
);
|
|
|
|
const result = chatCompletion.choices[0]?.message.content;
|
|
if (!result) {
|
|
//7. throwing an error at the top-level in v2 failed the task immediately
|
|
throw new Error("No result from OpenAI");
|
|
}
|
|
|
|
//8. io.runTask needed to be used to prevent work from happening twice
|
|
const dbRow = await io.runTask("store-in-db", async (task) => {
|
|
//9. Custom logic can be put here
|
|
// Anything returned must be JSON-serializable, so no Date objects etc.
|
|
return saveToDb(result);
|
|
});
|
|
|
|
//10. Wait for 5 minutes.
|
|
// You need a cacheKey and the 2nd param is a number
|
|
await io.wait("wait some time", 60 * 5);
|
|
|
|
//11. Anything returned must be JSON-serializable, so no Date objects etc.
|
|
return result;
|
|
},
|
|
});
|
|
```
|
|
|
|
### v3
|
|
|
|
In v3 we eliminate a lot of code mainly because we don't need tricks to try avoid timeouts. Here's the equivalent v3 code:
|
|
|
|
```ts v3 OpenAI task
|
|
import { logger, task, wait } from "@trigger.dev/sdk/v3";
|
|
|
|
//1. Official OpenAI SDK
|
|
import OpenAI from "openai";
|
|
const openai = new OpenAI({
|
|
apiKey: process.env.OPENAI_API_KEY,
|
|
});
|
|
|
|
//2. Jobs don't exist now, use "task"
|
|
export const openaiTask = task({
|
|
id: "openai-task",
|
|
//3. Retries happen if a task throws an error that isn't caught
|
|
// The default settings are in your trigger.config.ts (used if not overriden here)
|
|
retry: {
|
|
maxAttempts: 3,
|
|
},
|
|
run: async (payload: { prompt: string }) => {
|
|
//4. Use the official SDK
|
|
//5. No timeouts, so this can take a long time
|
|
const chatCompletion = await openai.chat.completions.create({
|
|
messages: [{ role: "user", content: payload.prompt }],
|
|
model: "gpt-3.5-turbo",
|
|
});
|
|
|
|
const result = chatCompletion.choices[0]?.message.content;
|
|
if (!result) {
|
|
//6. throwing an error at the top-level will retry the task (if retries are enabled)
|
|
throw new Error("No result from OpenAI");
|
|
}
|
|
|
|
//7. No need to use runTask, just call the function
|
|
const dbRow = await saveToDb(result);
|
|
|
|
//8. You can provide seconds, minutes, hours etc.
|
|
// You don't need cacheKeys in v3
|
|
await wait.for({ minutes: 5 });
|
|
|
|
//9. You can return anything that's serializable using SuperJSON
|
|
// That includes undefined, Date, bigint, RegExp, Set, Map, Error and URL.
|
|
return result;
|
|
},
|
|
});
|
|
```
|
|
|
|
## Triggering tasks comparison
|
|
|
|
### v2
|
|
|
|
In v2 there were different trigger types and triggering each type was slightly different.
|
|
|
|
```ts v2 triggering
|
|
async function yourBackendFunction() {
|
|
//1. for `eventTrigger` you use `client.sendEvent`
|
|
const event = await client.sendEvent({
|
|
name: "openai.tasks",
|
|
payload: { prompt: "Create a good programming joke about background jobs" },
|
|
});
|
|
|
|
//2. for `invokeTrigger` you'd call `invoke` on the job
|
|
const { id } = await invocableJob.invoke({
|
|
prompt: "What is the meaning of life?",
|
|
});
|
|
}
|
|
```
|
|
|
|
### v3
|
|
|
|
We've unified triggering in v3. You use `trigger()` or `batchTrigger()` which you can do on any type of task. Including scheduled, webhooks, etc if you want.
|
|
|
|
```ts v3 triggering
|
|
async function yourBackendFunction() {
|
|
//call `trigger()` on any task
|
|
const handle = await openaiTask.trigger({
|
|
prompt: "Tell me a programming joke",
|
|
});
|
|
}
|
|
```
|
|
|
|
## Upgrading your project
|
|
|
|
1. Make sure to upgrade all of your trigger.dev packages to v3 first.
|
|
|
|
```bash
|
|
npx @trigger.dev/cli@beta update --to beta
|
|
```
|
|
|
|
2. Follow the [v3 quick start](/v3/quick-start) to get started with v3. Our new CLI will take care of the rest.
|
|
|
|
## Using v2 together with v3
|
|
|
|
You can use v2 and v3 in the same codebase. This can be useful where you already have v2 jobs or where we don't support features you need (yet).
|
|
|
|
<Note>We do not support calling v3 tasks from v2 jobs or vice versa.</Note>
|