1.0.9 • Published 1 month ago

@scandinaviatech/scheduled-timers v1.0.9

Weekly downloads
-
License
ISC
Repository
-
Last release
1 month ago

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);
}
1.0.9

1 month ago

1.0.8

1 month ago

1.0.7

1 month ago

1.0.6

1 month ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago