Scheduler and Cron Jobs
Every system needs to run some tasks periodically. Pashmak provides a simple way to define and run scheduled tasks using cron syntax.
Basic Usage
import { scheduler } from "@devbro/pashmak/facades";
scheduler()
.call(async () => {
console.log("This runs every minute");
})
.setCronTime("* * * * *")
.setName("cleanup cron job")
.setRunOnStart(true);
Cron Syntax
The cron syntax follows the standard format:
* * * * *
│ │ │ │ │
│ │ │ │ └─── Day of week (0-7, where 0 and 7 are Sunday)
│ │ │ └───── Month (1-12)
│ │ └─────── Day of month (1-31)
│ └───────── Hour (0-23)
└─────────── Minute (0-59)
Common Examples
// Every minute
scheduler().call(handler).setCronTime("* * * * *");
// Every hour at minute 0
scheduler().call(handler).setCronTime("0 * * * *");
// Every day at midnight
scheduler().call(handler).setCronTime("0 0 * * *");
// Every Monday at 9 AM
scheduler().call(handler).setCronTime("0 9 * * 1");
// Every 15 minutes
scheduler().call(handler).setCronTime("*/15 * * * *");
// First day of every month at midnight
scheduler().call(handler).setCronTime("0 0 1 * *");
Scheduler Methods
start() and stop()
Control the scheduler's execution:
import { scheduler } from "@devbro/pashmak/facades";
// Start all scheduled tasks
scheduler().start();
// Stop all scheduled tasks
scheduler().stop();
getSchedules()
Get all currently registered schedules:
const schedules = scheduler().getSchedules();
console.log(`Found ${schedules.length} scheduled tasks`);
findSchedule(name)
Find a specific schedule by its name:
const schedule = scheduler().findSchedule("cleanup cron job");
if (schedule) {
console.log("Schedule found");
}
Note: Schedules must have a name set via .setName() to be findable.
getScheduleNames()
Get all schedule names:
const names = scheduler().getScheduleNames();
console.log("Scheduled tasks:", names);
setErrorHandler(handler)
Set a global error handler for all scheduled tasks:
import { logger } from "@devbro/pashmak/facades";
scheduler().setErrorHandler(async (error, scheduleName) => {
logger().error({
msg: "Scheduled task failed",
scheduleName,
error: error.message,
});
// Send notification, log to external service, etc.
});
setContextWrapper(func)
Set a custom context wrapper function. This is an advanced feature for switching the context provider:
scheduler().setContextWrapper((fn) => {
// Your custom context wrapper implementation
return fn();
});
Warning: Only use this if you understand the context management system.
Complete Example
// src/schedulers.ts
import { scheduler } from "@devbro/pashmak/facades";
import { logger } from "@devbro/pashmak/facades";
import { User } from "./app/models/User";
// Clean up old sessions every day at 2 AM
scheduler()
.call(async () => {
logger().info("Starting session cleanup");
const deleted = await Session.deleteOlderThan(30); // days
logger().info({ msg: "Session cleanup complete", deleted });
})
.setCronTime("0 2 * * *")
.setName("session_cleanup")
.setRunOnStart(false);
// Send daily digest emails every day at 8 AM
scheduler()
.call(async () => {
logger().info("Sending daily digest emails");
const users = await User.getActiveUsers();
for (const user of users) {
await sendDigestEmail(user);
}
logger().info({ msg: "Digest emails sent", count: users.length });
})
.setCronTime("0 8 * * *")
.setName("daily_digest")
.setRunOnStart(false);
// Health check every 5 minutes
scheduler()
.call(async () => {
const healthy = await performHealthCheck();
if (!healthy) {
logger().error("Health check failed!");
}
})
.setCronTime("*/5 * * * *")
.setName("health_check")
.setRunOnStart(true); // Run immediately on startup
// Set error handler
scheduler().setErrorHandler(async (error, scheduleName) => {
logger().error({
msg: "Scheduled task error",
task: scheduleName,
error: error.message,
stack: error.stack,
});
});
Running the Scheduler
by default, the scheduler is start when the http server using --all flag.
npm run pdev start --all
# or
yarn pdev start --scheduler
# or
pnpm pdev start --cron # alternative name for --scheduler