Skip to content

Instantly share code, notes, and snippets.

@scinscinscin
Last active July 20, 2023 13:21
Show Gist options
  • Save scinscinscin/f986dbb2c56b158c36048fe257cb77b2 to your computer and use it in GitHub Desktop.
Save scinscinscin/f986dbb2c56b158c36048fe257cb77b2 to your computer and use it in GitHub Desktop.
A scheduler that calls a function with a unique identifier at a specific time
import schedule from "node-schedule";
import { logger } from "./winston.js";
/**
* A scheduler that calls a function with a unique identifier at a specific time
* @param type_T - the type of the unique identifier to track each job
*/
export class Scheduler<T> {
private jobs: Map<T, schedule.Job> = new Map();
/**
* Create a scheduler instance
* @param callback - Function to be executed when a scheduled job fires. It takes in a unique identifier.
*/
public constructor(private readonly callback: (unique_identifier: T) => Promise<void>) {}
/**
* Schedule a job to run on a specific date
* @param date The date to run the callback. Returns with warning if the date is in the past.
* @param uuid The unique identifier that will be passed into the callback
*/
schedule(date: Date, uuid: T) {
if (date.valueOf() < Date.now()) {
logger.warn(`Not adding job uuid: ${uuid} scheduled for the past`);
return;
}
this.cancel(uuid);
const newJob = schedule.scheduleJob(date, () => {
this.callback(uuid)
.then(() => {
logger.info(`Finished performing job: ${uuid} on ${date.valueOf()}`);
})
.catch(() => {
logger.warn(`Failed performing job: ${uuid} on ${date.valueOf()}`);
});
});
this.jobs.set(uuid, newJob);
}
/**
* Cancel a job based on the unique identifier
* @param uuid - The identifier of the job to cacnel
*/
cancel(uuid: T) {
const oldJob = this.jobs.get(uuid);
if (oldJob) {
oldJob.cancel();
this.jobs.delete(uuid);
}
}
/**
* Load a batch of jobs
* @param jobs An array containing the uuid of the jobs and the date to execute them.
*/
loadJobs(jobs: { uuid: T; date: Date }[]) {
for (const job of jobs) {
this.schedule(job.date, job.uuid);
}
}
print() {
this.jobs.forEach((job, uuid) => {
console.log(`${uuid} scheduled to be posted on ${job.nextInvocation()}`);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment