workflow-cron-sleep 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,14 +88,14 @@ Throws an error if the cron expression is invalid or has no future occurrences.
|
|
|
88
88
|
|
|
89
89
|
Since `cronSleep` only sleeps until the **next** occurrence, you need to design your workflow architecture to handle recurring schedules.
|
|
90
90
|
|
|
91
|
-
### Pattern:
|
|
91
|
+
### Pattern: While Loop Scheduler
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
The simplest approach is a single workflow with a `while (true)` loop that sleeps and triggers your business logic workflow repeatedly:
|
|
94
94
|
|
|
95
95
|
**`workflows/report-scheduler.ts`** - The scheduler workflow
|
|
96
96
|
```typescript
|
|
97
97
|
import { cronSleep } from "workflow-cron-sleep"
|
|
98
|
-
import {
|
|
98
|
+
import { triggerReportProcessor } from "./steps"
|
|
99
99
|
|
|
100
100
|
export interface ReportSchedulerInput {
|
|
101
101
|
reportId: string
|
|
@@ -107,57 +107,65 @@ export async function reportScheduler(input: ReportSchedulerInput) {
|
|
|
107
107
|
|
|
108
108
|
const { reportId, cronExpression } = input
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
while (true) {
|
|
111
|
+
// Wait for the next scheduled time
|
|
112
|
+
await cronSleep(cronExpression, { timezone: "America/New_York" })
|
|
113
|
+
|
|
114
|
+
// Trigger the processor workflow
|
|
115
|
+
await triggerReportProcessor(reportId)
|
|
116
|
+
}
|
|
115
117
|
}
|
|
116
118
|
```
|
|
117
119
|
|
|
118
|
-
**`workflows/
|
|
120
|
+
**`workflows/steps.ts`** - Step function to start the processor
|
|
119
121
|
```typescript
|
|
120
|
-
import {
|
|
122
|
+
import { start } from "workflow/api"
|
|
123
|
+
import { reportProcessorWorkflow } from "./report-processor"
|
|
124
|
+
|
|
125
|
+
export async function triggerReportProcessor(reportId: string) {
|
|
126
|
+
"use step"
|
|
127
|
+
await start(reportProcessorWorkflow, [{ reportId }])
|
|
128
|
+
}
|
|
129
|
+
```
|
|
121
130
|
|
|
131
|
+
**`workflows/report-processor.ts`** - The processor workflow (business logic)
|
|
132
|
+
```typescript
|
|
122
133
|
export interface ReportProcessorInput {
|
|
123
134
|
reportId: string
|
|
124
|
-
cronExpression: string
|
|
125
135
|
}
|
|
126
136
|
|
|
127
137
|
export async function reportProcessorWorkflow(input: ReportProcessorInput) {
|
|
128
138
|
"use workflow"
|
|
129
139
|
|
|
130
|
-
const { reportId
|
|
140
|
+
const { reportId } = input
|
|
131
141
|
|
|
132
|
-
// Your business logic here
|
|
142
|
+
// Your business logic here - completely agnostic to scheduling
|
|
133
143
|
await generateReport(reportId)
|
|
134
144
|
await sendNotifications(reportId)
|
|
135
|
-
|
|
136
|
-
// Restart the scheduler for the next occurrence
|
|
137
|
-
await restartScheduler(reportId, cronExpression)
|
|
138
145
|
}
|
|
139
146
|
```
|
|
140
147
|
|
|
141
|
-
|
|
148
|
+
### Starting and Canceling
|
|
149
|
+
|
|
142
150
|
```typescript
|
|
143
|
-
import { start } from "workflow"
|
|
144
|
-
import {
|
|
145
|
-
import { reportScheduler } from "./report-scheduler"
|
|
151
|
+
import { start, getRun } from "workflow/api"
|
|
152
|
+
import { reportScheduler } from "./workflows/report-scheduler"
|
|
146
153
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
// Start the cron scheduler
|
|
155
|
+
const run = await start(reportScheduler, [{
|
|
156
|
+
reportId: "daily-report",
|
|
157
|
+
cronExpression: "0 9 * * *"
|
|
158
|
+
}])
|
|
151
159
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
await start(reportScheduler, [{ reportId, cronExpression }])
|
|
155
|
-
}
|
|
156
|
-
```
|
|
160
|
+
// Save the run ID to cancel later
|
|
161
|
+
await db.cronJobs.create({ runId: run.id })
|
|
157
162
|
|
|
158
|
-
|
|
163
|
+
// To cancel the cron (stops the while loop)
|
|
164
|
+
const currentRun = getRun(run.id)
|
|
165
|
+
await currentRun.cancel()
|
|
166
|
+
```
|
|
159
167
|
|
|
160
|
-
|
|
168
|
+
This pattern keeps your scheduling and business logic decoupled. The scheduler runs forever, triggering your processor workflow on schedule. Save the `runId` so you can cancel if the cron expression changes or the job is no longer needed.
|
|
161
169
|
|
|
162
170
|
## Requirements
|
|
163
171
|
|