@scandinaviatech/scheduled-timers
v1.0.9
Published
This package can be used to create cron base timers, which can be used to run a job at a specific time.
Downloads
10
Readme
Scheduled Timers
This package can be used to create cron base timers, which can be used to run a job at a specific time.
How does it work ?
The package depends on three main components
- Cron Scheduler: used to schedule timer job which runs every minute by default (can be overridden).
- Storage Engine: used to store jobs information that will be run in the future.
- Job Provider: used to execute jobs that are scheduled to run.
- Id Provider: used to generate random ids for jobs.
Cron Scheduler
The cron scheduler is used to schedule the job for fetching next jobs to be executed, you can provide your own implemenation of the cron scheduler or use the one provided by the package which is based on node-schedule
package.
Using node-schedule
import { Timer } from "@scandinaviatech/scheduled-timers";
/* import node-schedule based scheduler */
import { NodeScheduleCronScheduler } from "@scandinaviatech/scheduled-timers/lib/cron/node-schedule/node-schedule";
const timer = new Timer({
...
/* pass scheduler to timer */
cronScheduler: new NodeScheduleCronScheduler(),
...
});
Using another implementation
import { Timer } from "@scandinaviatech/scheduled-timers";
import { CronScheduler } from "@scandinaviatech/scheduled-timers/lib/cron/cron.interface";
/* create you own implemenation of the cron scheduler */
const scheduler: CronScheduler = {
schedule(cron: string, job: () => any) {
/* use passed cron to schedule the job */
}
}
const timer = new Timer({
...
/* pass scheduler to timer */
cronScheduler: scheduler,
...
});
Storage Engine
storage engines is used to store jobs that should be executed in the future, you can provide your own implementation of the storage engine or use the one of the storage engines provided by the package which are mongodb
storage engine and in-memory
storage engine.
Using mongodb
based storage
mongodb storage will store jobs that will be executed in the future in mongodb collections, you must provide the collection name to the mongodb storage component.
/* import mongodb storage */
import { MongodbTimerStorage } from "@scandinaviatech/scheduled-timers/lib/storage/mongodb/mongodb-storage";
/* provide collection name for timers to be stored in */
const collection = connection.collection('timers');
const timer = new Timer({
...
/* pass storage engine to timer */
storage: new MongodbTimerStorage(collection),
...
})
Using in-memory
based storage
stores jobs that will be executed in the future in memory, you can use this storage if you don't want to store jobs in a database and don't care about losing scheduled jobs when server restarts.
/* import mongodb storage */
import { InMemeoryTimerStorage } from "@scandinaviatech/scheduled-timers/lib/storage/in-memory/in-memory-storage";
const timer = new Timer({
...
/* pass storage engine to timer */
storage: new InMemeoryTimerStorage(),
...
})
Using another implementation
You can provide you own implemenation of storage engine, for example using mysql
ot postgresql
.
/* import mongodb storage */
import { TimerStorage, StoredCronJob } from "@scandinaviatech/scheduled-timers/lib/storage/timer-storage.interface";
const storage: TimerStorage = {
insert(job: StoredCronJob<T>): void | Promise<void> {
/* insert scheduled job in storage */
};
deleteById(id: string): void | Promise<void> {
/* delete scheduled job from storage */
};
updateById(id: string, job: Partial<StoredCronJob<T>>): void | Promise<void> {
/* update scheduled job */
}
findById(
id: string
):
| StoredCronJob<T>
| null
| undefined
| Promise<StoredCronJob<T> | null | undefined> {
/* retrieve a job by id */
};
findByNextInvocation(
compareTo?: Date
): StoredCronJob<T>[] | Promise<StoredCronJob<T>[]> {
/* retrieve jobs that passed the next invocation date */
};
}
const timer = new Timer({
...
/* pass your storage engine to timer */
storage: new storage(),
...
})
Job Provider
Job provider is used to execute jobs that are scheduled to run, you should provide your own implementation of how jobs must be executed once their time comes.
import { JobProvider } from '@scandinaviatech/scheduled-timers';
/* these args are passed to the job provider whenever a job is to be executed */
type JobArgs = [...]
const jobProvider: JobProvider = {
job(...args: JobArgs) {
return () => {
/* run your own logic here, you can use args to determin how to run the job */
}
},
};
const timer = new Timer({
...
/* pass your job proivder to timer */
jobProvider: jobProvider,
...
});
Id Provider
Id provider is used to generate ids for registerd jobs, this is required since the storage engine in unknow, so in case of in-memory type storage engine, you need to explicitly generate the id, so we ended up using the generate id in general for all storage engines.
Using uuid
based
import { CryptoUUIDIDProvider } from "@scandinaviatech/scheduled-timers/lib/id-provider/crypto-uuid/crypto-uuid-id-provider";
const idProvider = new CryptoUUIDIDProvider();
const timer = new Timer({
...
/* pass id provider to timer */
idProvider: idProvider,
...
});
Using another implementation
import { IdProvider } from "@scandinaviatech/scheduled-timers/lib/id-provider/id-provider.interface";
const idProvider: IdProvider = {
id(): string | Promise<string> {
/* generate and return the random id */
}
};
const timer = new Timer({
...
/* pass id provider to timer */
idProvider: idProvider,
...
});
Registering Jobs
To schedule jobs for execution in the future you need to use the timer instance to schdule jobs.
const timer: Timer;
...
/* initialize timer */
...
/* prepare your args */
const args: YourJobArgs = [...]
/* register the job */
const { id } = await this.timer.addCron(cron, args);
/* you can use the id to cancel or edit the job later */
/* once job time comes, the job provider will be run using the provided args */
Complete Example
The following example shows how to use the package to schedule jobs for execution in the future.
import { Timer } from "@scandinaviatech/scheduled-timers";
import { NodeScheduleCronScheduler } from "@scandinaviatech/scheduled-timers/lib/cron/node-schedule/node-schedule";
import { CryptoUUIDIDProvider } from "@scandinaviatech/scheduled-timers/lib/id-provider/crypto-uuid/crypto-uuid-id-provider";
import { MongodbTimerStorage } from "@scandinaviatech/scheduled-timers/lib/storage/mongodb/mongodb-storage";
import { Collection } from "mongodb";
type JobArgs = [id: number, document: { type: "doc-a" | "doc-b", value: number }];
// collection to store timers documents and arguments.
const collection: Collection = connection.collection("timers");
const jobProvider: JobProvider<JobArgs> = {
job(id: number, document: { type: "doc-a" | "doc-b", value: number }) {
return () => {
switch (document.type) {
case "doc-a":
console.log("Executing Doc A Type Job")
break;
case "doc-b":
console.log("Executing Doc B Type Job")
break;
}
}
},
};
const timer = new Timer({
cronScheduler: new NodeScheduleCronScheduler(),
idProvider: new CryptoUUIDIDProvider(),
storage: new MongodbTimerStorage(collection),
jobProvider: jobProvider,
});
/* define a function that can be triggered by some action */
async function addJob() {
/* define args */
const args: JobArgs = [1, { type: 'doc-a', value: 5 }];
/* register the job to be run every hour */
const { id } = await timer.addCron("0 * * * *", args);
}
async function removeJob(id: number) {
/* remove the cron using the provided id */
await timer.removeCron(id);
}