Cron Scheduling¶
Schedule tasks to run automatically using cron expressions, either statically at startup or dynamically at runtime.
Static Cron Schedules¶
Define cron schedules when creating tasks:
const dailyReport = conductor.createTask(
{ name: "daily-report" },
{ cron: "0 9 * * *", name: "morning-report" }, // 9 AM daily
async (event, ctx) => {
ctx.logger.info("Generating daily report");
// Generate report
}
);
The orchestrator automatically schedules the next execution after each run. If the task fails and retries, it still reschedules the next execution.
Multiple Schedules & Event Handling¶
A task can have multiple cron schedules and be invocable. Use event.name to distinguish between triggers:
const notification = conductor.createTask(
{ name: "send-digest" },
[
{ invocable: true },
{ cron: "0 9 * * *", name: "morning" }, // 9 AM
{ cron: "0 17 * * *", name: "evening" }, // 5 PM
],
async (event, ctx) => {
if (event.name === "morning") {
ctx.logger.info("Sending morning digest");
// Morning-specific logic
} else if (event.name === "evening") {
ctx.logger.info("Sending evening digest");
// Evening-specific logic
} else if (event.name === "pgconductor.invoke") {
// Manually invoked
const payload = event.payload;
}
}
);
Each schedule runs independently. The event.name property contains the schedule name for cron triggers or "pgconductor.invoke" for manual invocations.
Dynamic Scheduling¶
Create and manage cron schedules at runtime using ctx.schedule():
const userPreferences = conductor.createTask(
{ name: "apply-preferences" },
{ invocable: true },
async (event, ctx) => {
const { userId, reportTime } = event.payload;
// Schedule personalized report
await ctx.schedule(
{ name: "user-report" },
`user-${userId}`, // Unique schedule name
{ cron: `0 ${reportTime} * * *` }, // Custom time
{ userId } // Payload for scheduled task
);
}
);
Parameters:
await ctx.schedule(
taskRef, // { name: "task-name", queue?: "queue-name" }
scheduleName, // Unique identifier for this schedule
cronOptions, // { cron: "expression" }
payload // Payload passed to task when it runs
);
Unschedule¶
Remove a dynamic schedule:
const cancelReport = conductor.createTask(
{ name: "cancel-user-report" },
{ invocable: true },
async (event, ctx) => {
const { userId } = event.payload;
// Remove the schedule
await ctx.unschedule(
{ name: "user-report" },
`user-${userId}`
);
}
);
This stops future executions and cancels any pending scheduled execution.
Schedule Names¶
Schedule names must be unique per task:
// ✅ Good - unique names
await ctx.schedule({ name: "task" }, "schedule-1", { cron: "..." }, {});
await ctx.schedule({ name: "task" }, "schedule-2", { cron: "..." }, {});
// ❌ Bad - duplicate name overwrites
await ctx.schedule({ name: "task" }, "schedule-1", { cron: "0 9 * * *" }, {});
await ctx.schedule({ name: "task" }, "schedule-1", { cron: "0 17 * * *" }, {}); // Overwrites
Deduplication¶
Multiple workers with the same cron schedule won't create duplicates:
// Worker 1
const orch1 = Orchestrator.create({
conductor,
tasks: [cronTask],
});
// Worker 2 - same task, same schedule
const orch2 = Orchestrator.create({
conductor,
tasks: [cronTask],
});
// Only one scheduled execution exists in database
What's Next?¶
- Delayed Execution - One-time scheduled tasks
- Task Triggers - Understand trigger types