type TaskPayload = { timestamp: Date; lastTimestamp?: Date; timezone: string; }; type TaskContext = { retriesLeft: number; }; type TaskArgs = { id: string; name: string; cron: string; maxDuration?: number; // saniye retries?: number; run: ( payload: TaskPayload, tools: { ctx: TaskContext } ) => Promise | void; }; export class Schedules { private lastRunTimestamps: Record = {}; private Tasks: TaskArgs[] = []; public task(args: TaskArgs) { this.Tasks.push(args); } public async run(taskId: string) { const now = new Date(); const lastTimestamp = this.lastRunTimestamps[taskId]; const payload: TaskPayload = { timestamp: now, lastTimestamp, timezone: "UTC", }; this.lastRunTimestamps[taskId] = now; const context: TaskContext = { retriesLeft: this.Tasks.find(task => task.id === taskId)?.retries ?? 0, }; await this.runWithRetry(this.Tasks.find(task => task.id === taskId)!, payload, context); } private async runWithRetry( task: TaskArgs, payload: TaskPayload, ctx: TaskContext ) { const start = Date.now(); try { await Promise.race([ task.run(payload, { ctx }), timeout(task.maxDuration ?? 60), ]); log("success", { taskId: task.id, name: task.name, time: new Date().toISOString() }); } catch (err) { //@ts-ignore log("error", { taskId: task.id, name: task.name, error: err }); if (ctx.retriesLeft > 0) { ctx.retriesLeft -= 1; //@ts-ignore log("warn", { taskId: task.id, name: task.name, msg: "Retrying..." }); await this.runWithRetry(task, payload, ctx); } } finally { const duration = Date.now() - start; //@ts-ignore log("info", { taskId: task.id, name: task.name, durationMs: duration }); } } public toJSON() { return this.Tasks.map(task => ({ id: task.id, name: task.name, cron: task.cron, maxDuration: task.maxDuration, retries: task.retries, })); } } function log(arg0: string, arg1: { taskId: string; name: string; time: string; }) { // console.log(arg0, arg1); } function timeout(seconds: number) { return new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout reached")), seconds * 1000) ); } export const schedules = new Schedules();