Added lastRunAt to the scheduleEvent payload

This commit is contained in:
Eric Allam
2023-01-26 10:12:57 +00:00
parent 1374c10d99
commit e37a2001e1
11 changed files with 148 additions and 24 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@trigger.dev/sdk": patch
---
Added lastRunAt to the scheduleEvent payload
+14 -5
View File
@@ -39,7 +39,11 @@
"navigation": [
{
"group": "Getting Started",
"pages": ["welcome", "getting-started", "get-help"]
"pages": [
"welcome",
"getting-started",
"get-help"
]
},
{
"group": "Examples",
@@ -67,11 +71,15 @@
"pages": [
{
"group": "Slack",
"pages": ["integrations/apis/slack/actions/post-message"]
"pages": [
"integrations/apis/slack/actions/post-message"
]
},
{
"group": "Resend.com",
"pages": ["integrations/apis/resend/actions/send-email"]
"pages": [
"integrations/apis/resend/actions/send-email"
]
}
]
},
@@ -102,7 +110,8 @@
"pages": [
"reference/trigger",
"reference/custom-event",
"reference/webhook-event"
"reference/webhook-event",
"reference/schedule-event"
]
},
{
@@ -128,4 +137,4 @@
"github": "https://github.com/triggerdotdev/trigger.dev",
"discord": "https://discord.gg/nkqV9xBYWy"
}
}
}
+2
View File
@@ -7,6 +7,8 @@ description: "Trigger a workflow when a custom event is received."
## Usage
```ts
import { customEvent, Trigger } from "@trigger.dev/sdk";
new Trigger({
id: "user-created-notify-slack",
name: "User Created - Notify Slack",
+68
View File
@@ -0,0 +1,68 @@
---
title: "scheduleEvent Trigger"
sidebarTitle: "scheduleEvent"
description: "Run a workflow on a recurring schedule."
---
## Usage
```ts
import { scheduleEvent } from "@trigger.dev/sdk";
new Trigger({
id: "usage",
name: "usage",
on: scheduleEvent({ rateof: { minutes: 10 } }),
run: async (event, ctx) => {},
}).listen();
```
## Options
You must use one of the following options, but not both:
<ParamField path="rateOf" type="object" required={false}>
The rate of the schedule. This can be a number of minutes, hours,
or days. For example, `{ rateOf: { minutes: 10 } }` will run
every 10 minutes.
</ParamField>
<ParamField path="cron" type="string" required={false}>
A cron expression to run the workflow on. For example, `0 0 * * *` will run
the workflow every hour at the top of the hour. See
[crontab.guru](https://crontab.guru/) for more information.
</ParamField>
## Event Payload
<ResponseField name="scheduledTime" type="Date" required={true}>
The time the event was scheduled to run.
</ResponseField>
<ResponseField name="lastRunAt" type="Date" required={false}>
The time the event last run. This will be `undefined` if the event has never run. Use this parameter to run window queries:
```ts
import { scheduleEvent, Trigger } from "@trigger.dev/sdk";
new Trigger({
id: "usage",
name: "usage",
on: scheduleEvent({ rateof: { minutes: 10 } }),
run: async (event, ctx) => {
const { lastRunAt, scheduledTime } = event;
const query = `SELECT * FROM users WHERE created_at < ${scheduledTime}`;
if (lastRunAt) {
query += ` AND created_at > ${lastRunAt}`;
}
const latestUsers = await db.query(query);
// ...
},
}).listen();
```
</ResponseField>
+2 -5
View File
@@ -9,6 +9,8 @@ description: "The Trigger class let's you define a workflow that is triggered by
### Usage
```ts
import { customEvent, Trigger } from "@trigger.dev/sdk";
const trigger = new Trigger({
id: "user-created-notify-slack",
name: "User Created - Notify Slack",
@@ -39,11 +41,6 @@ const trigger = new Trigger({
`TRIGGER_API_KEY` environment variable.
</ParamField>
<ParamField path="apiKey" type="string" required={false}>
Your Trigger.dev API key. If not provided, the API key will be read from the
`TRIGGER_API_KEY` environment variable.
</ParamField>
<ParamField path="endpoint" type="string" required={false}>
The URL of the Trigger.dev WebSocket server. If not provided, the endpoint
will point to the production server.
+2
View File
@@ -7,6 +7,8 @@ description: "Trigger a workflow when a webhook event is received"
## Usage
```ts
import { webhookEvent, Trigger } from "@trigger.dev/sdk";
new Trigger({
id: "caldotcom-to-slack",
name: "Cal.com To Slack",
+32
View File
@@ -4,6 +4,8 @@ sidebarTitle: "Scheduled"
description: "Run a workflow on a recurring schedule"
---
See the [reference](/reference/schedule-event) for more details.
## Examples
### Every 5 minutes
@@ -51,3 +53,33 @@ new Trigger({
},
}).listen();
```
## Preventing late runs
To prevent a scheduled trigger from running late, you can set a `triggerTTL` option when creating the `Trigger`, like so:
```ts
new Trigger({
id: "scheduled-workflow",
name: "Scheduled Workflow",
apiKey: "<your_api_key>",
on: scheduleEvent({ rateOf: { minutes: 5 } }),
triggerTTL: 300,
run: async (event, ctx) => {
await ctx.logger.info("Received the scheduled event", {
event,
wallTime: new Date(),
});
return { foo: "bar" };
},
}).listen();
```
This will prevent the trigger from running if it is running more than `300` seconds behind, which can happen if the server running your `Trigger` code goes down or is otherwise unavailable.
This is especially useful for scheduled triggers that run on a very short interval, like every minute, so you don't get a backlog of runs that all run at once when the server comes back online.
<Tip>
Set your `triggerTTL` to the same time (or double) as the rateOf the trigger.
</Tip>
@@ -29,7 +29,13 @@ export class ScheduleNextEvent {
const messageId = await taskQueue.publish(
"DELIVER_SCHEDULED_EVENT",
{ externalSourceId: schedulerSource.id, payload: { scheduledTime } },
{
externalSourceId: schedulerSource.id,
payload: {
scheduledTime,
lastRunAt: fromEvent ? fromEvent.createdAt : undefined,
},
},
{},
{ deliverAt: scheduledTime.getTime() }
);
@@ -5,19 +5,20 @@ import { prisma } from "~/db.server";
export const uptimeCheck = new Trigger({
id: "uptime-check",
name: "Uptime Check",
on: scheduleEvent({ rateOf: { minutes: 1 } }),
triggerTTL: 300,
on: scheduleEvent({ rateOf: { minutes: 5 } }),
logLevel: "info",
triggerTTL: 60,
run: async (event, context) => {
if (context.environment === "development" && !context.isTest) {
return;
}
// Grab counts of workflows, runs, and steps
const userCount = await prisma.user.count();
const workflowCount = await prisma.workflow.count();
const runCount = await prisma.workflowRun.count();
const stepCount = await prisma.workflowRunStep.count();
if (context.environment === "development") {
return;
}
await slack.postMessage("Uptime Notification", {
channelName: "monitoring",
text: `[${context.environment}] Uptime Check: ${userCount} users, ${workflowCount} workflows, ${runCount} runs, ${stepCount} steps.`,
+8 -7
View File
@@ -2,20 +2,21 @@ import { Trigger, scheduleEvent } from "@trigger.dev/sdk";
import { slack } from "@trigger.dev/integrations";
const trigger = new Trigger({
id: "schedule-to-slack",
id: "schedule-to-slack-2",
name: "Send to Slack every minute",
apiKey: "trigger_development_vzNnO2DGBGcG",
apiKey: "trigger_dev_zC25mKNn6c0q",
endpoint: "ws://localhost:8889/ws",
logLevel: "debug",
on: scheduleEvent({ rateOf: { minutes: 1 } }),
run: async (event, ctx) => {
await ctx.logger.info("It's me, the annoying slack bot!");
const response = await slack.postMessage("slaaaaaack", {
channel: "test-integrations",
text: `Hello, the time is ${event.scheduledTime}`,
});
// const response = await slack.postMessage("slaaaaaack", {
// channelName: "test-integrations",
// text: `Hello, the time is ${event.scheduledTime}, and I was last run at ${event.lastRunAt}!`,
// });
return response.message;
return event;
},
});
+1
View File
@@ -29,6 +29,7 @@ export const EventFilterSchema: z.ZodType<EventFilter> = z.lazy(() =>
);
export const ScheduledEventPayloadSchema = z.object({
lastRunAt: z.coerce.date().optional(),
scheduledTime: z.coerce.date(),
});