@uisap/core
Version:
A modular Fastify-based framework inspired by Laravel
239 lines (209 loc) • 6.24 kB
JavaScript
import { ToadScheduler, AsyncTask, CronJob } from "toad-scheduler";
import { QueueFacade as Queue } from "./facades.js";
export class Schedule {
constructor(app) {
this.app = app;
this.scheduler = new ToadScheduler();
this.pendingTasks = [];
this.tasks = [];
this.timezone = this.app.config.schedule?.timezone || "Europe/Istanbul";
}
addTask(type, options) {
const task = { type, ...options };
this.pendingTasks.push(task);
this.tasks.push(task);
return this;
}
call(callback, cronExpression = "* * * * *") {
return this.addTask("call", { callback, cronExpression });
}
queue(queueName, data, cronExpression = "* * * * *") {
return this.addTask("queue", { queueName, data, cronExpression });
}
command(signature, cronExpression = "* * * * *", options = {}) {
return this.addTask("command", { signature, cronExpression, options });
}
everySecond() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "* * * * * *",
});
}
everyTwoSeconds() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/2 * * * * *",
});
}
everyFiveSeconds() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/5 * * * * *",
});
}
everyTenSeconds() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/10 * * * * *",
});
}
everyFifteenSeconds() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/15 * * * * *",
});
}
everyThirtySeconds() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/30 * * * * *",
});
}
everyMinute() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "* * * * *",
});
}
everyTwoMinutes() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/2 * * * *",
});
}
everyFiveMinutes() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/5 * * * *",
});
}
everyTenMinutes() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/10 * * * *",
});
}
everyFifteenMinutes() {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: "*/15 * * * *",
});
}
hourly(minutes = 0) {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minutes} * * * *`,
});
}
daily(time = "0:00") {
const lastTask = this.pendingTasks.pop();
const [hour, minute] = time.split(":");
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minute} ${hour} * * *`,
});
}
twiceDaily(hour1, hour2, minute = 0) {
const lastTask = this.pendingTasks.pop();
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minute} ${hour1},${hour2} * * *`,
});
}
weekly(day = 0, time = "0:00") {
const lastTask = this.pendingTasks.pop();
const [hour, minute] = time.split(":");
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minute} ${hour} * * ${day}`,
});
}
monthly(day = 1, time = "0:00") {
const lastTask = this.pendingTasks.pop();
const [hour, minute] = time.split(":");
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minute} ${hour} ${day} * *`,
});
}
quarterly(day = 1, time = "0:00") {
const lastTask = this.pendingTasks.pop();
const [hour, minute] = time.split(":");
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minute} ${hour} ${day} */3 *`,
});
}
yearly(month = 1, day = 1, time = "0:00") {
const lastTask = this.pendingTasks.pop();
const [hour, minute] = time.split(":");
return this.addTask(lastTask.type, {
...lastTask,
cronExpression: `${minute} ${hour} ${day} ${month} *`,
});
}
setTimezone(timezone) {
this.timezone = timezone;
return this;
}
run() {
this.pendingTasks.forEach((task) => {
const taskFn =
task.type === "call"
? async () => await task.callback(this.app)
: task.type === "queue"
? async () => {
await Queue.push(task.queueName, task.data);
this.app.fastify.logger.info(
`Kuyruk görevi eklendi: ${task.queueName}`
);
}
: async () => {
const consoleKernel = this.app.container.make("consoleKernel");
await consoleKernel.run(task.signature, task.options);
};
const errorHandler = (err) =>
this.app.fastify.logger.error(`${task.type} zamanlama hatası`, {
error: err.message,
});
const cronJob = new CronJob(
{
cronExpression: task.cronExpression || "* * * * *",
timezone: this.timezone,
},
new AsyncTask(`${task.type}-${Date.now()}`, taskFn, errorHandler)
);
this.scheduler.addCronJob(cronJob);
});
this.pendingTasks = [];
this.app.fastify.logger.info("Zamanlayıcı başlatıldı");
}
listTasks() {
return this.tasks.map((task) => ({
type: task.type,
cronExpression: task.cronExpression,
details:
task.type === "call"
? "Callback"
: task.type === "queue"
? `${task.queueName}: ${JSON.stringify(task.data)}`
: `${task.signature} ${JSON.stringify(task.options)}`,
}));
}
stop() {
this.scheduler.stop();
this.app.fastify.logger.info("Zamanlayıcı durduruldu");
}
}