@marceliwac/moleculer-cron v0.0.3
Moleculer microservice framework mixin that adds cron job functionality. Under the hood, this mixin uses cron package to create and run jobs and wraps them into configuration objects that are used throughout the Moleculer's service lifecycle.
Installation
To install the package, run the following in your Moleculer project:
npm install @marceliwac/moleculer-cronBasic Usage
You can integrate this mixin into the existing service by importing it at the top of the file,
providing the mixin into the top-level service mixins field and specifying top-level crons field
which stores the array of your job configurations.
The only required configuration properties are cronTime, defining the cron pattern that describes
when your job should run and onTick, which is the function that will be run. You might however
also want to specify the start parameter to automatically start the job when the service starts.
In your onTick function you will be able to access the service context within this, similarly to
the service actions and methods. Examples of more detailed configuration for both JavaScript and
TypeScript can be found in examples.
import {Cron} from '@marceliwac/moleculer-cron';
// const {Cron} = require('@marceliwac/cron');
const service = {
name: "example",
mixins: [Cron], // enable the Cron Mixin
crons: [
{
cronTime: '* * * * *',
onTick: async function () {
this.logger.info(`Running job "simple job".`);
const randomNumber = await this.broker.call('example.getRandomNumber');
this.logger.info(`Random number is: ${randomNumber}`);
},
start: true,
}
],
actions: {
getRandomNumber: {
handler() {
const random = Number.parseInt((Math.random() * 10).toString());
this.logger.info(`Returning random number (${random}).`);
return random;
}
}
}
};API
There are many more configuration options you can use with each cron job. Below is a complete breakdown of the parameters that can be specified to further customise the behaviour of the jobs:
Configuration API
// Following properties are defined on the CronMixinConfig interface and can be used as part of the
// job configuration.
interface CronMixinConfig {
name?: string;
cronTime: string | Date | luxon.DateTime;
onTick: (onComplete?: (() => void | Promise<void>) | null) => void | Promise<void>;
onInitialise?: () => void | Promise<void>;
onStart?: () => void | Promise<void>;
onStop?: () => void | Promise<void>;
onComplete?: () => void | Promise<void>;
start?: boolean | null;
runOnInit?: boolean | null;
context?: object;
timeZone?: string | null;
utcOffset?: number | null;
unrefTimeout?: boolean | null;
}nameDefines the name that can be used to find the job usinggetCron()function. By default, a UUID v4 will be provided.cronTimeSpecifies when the job should run using a cron pattern with additional, optional field for the seconds. For full specification, see crontab specification and cron documentation.onTickFunction to be executed at the specifiedcronTime. This function will receive additional context from thecontextparameter, as well as Moleculer's service context.onInitialiseFunction to be executed before the cron job is created. This function will receive additional context from thecontextparameter, as well as Moleculer's service context.onStartFunction to be executed after the cron job is created. This function will receive additional context from thecontextparameter, as well as Moleculer's service context.onStopFunction to be executed after the cron job is stopped, or after the service stops. This function will receive additional context from thecontextparameter, as well as Moleculer's service context.onCompleteSimilarly toonStop, this function will be executed after the cron job is stopped. However, when defined, this function will also be provided as the first argument to theonTickfunction allowing you to manually call it with everyonTickcall. UnlikeonStop, this function will not receive any additional context when called when the job stops. It could however be called with any context (including thecontextparameter, as well as the Moleculer's service context) when called with everyonTick(for more details, see examples).startDefines whether this job should be started when the service is created. Crucially, this is different from therunOnInit, as it only "enables" the job without triggering itsonTick, allowing it to run on the next specifiedcronTime.runOnInitSpecifies whether theonTickshould be fired immediately following the job creation, regardless of thecronTimeorstartparameter. Following this initial call, all future calls will respect thecronTimeandstartparameters and only run at specified times if the job is started.contextAllows to supply additional context to the job which on top of the service context, which is always provided. Similarly to the service context, this value will also be passed to all the lifecycle handles (onTick,onInitialise,onStart,onStop) exceptonComplete.timeZoneSpecifies the timezone that should be used for the cronTime configuration. This is particularly important when thecronTimedefines a specific hour, day, month or day of the week, or a specific range for any of those values. Use oftimeZoneandutcOffsetis mutually exclusive.utcOffsetAlternative to thetimeZonewhich allows for specifying the offset to the UTC timezone in minutes. Both positive and negative values can be used (e.g.60would be UTC+1,-120would be UTC-2). Use ofutcOffsetandtimeZoneis mutually exclusive.unrefTimeoutSpecifies whether the running job should keep the process alive. This parameter is used internally by cron to control the event loop behaviour. When used with Moleculer Runner, this parameter won't affect the event loop behaviour because it is already controlled by the runner (it can be left unspecified).
Note: When defining your crons, make sure to use the
functions, which can inherit the context, rather than arrow functions / lambdas (() => {}).
Methods
This mixin also exposes additional methods that can be used to assist you with managing the jobs
during runtime. They can be accessed using the service context, and are therefore available across
the service, including other methods, actions and the lifecycle functions of the crons you define
(onTick, onInitialise, onStart, onStop) except onComplete which is called internally by
cron and therefore does not inherit the context.
CronJob API
Once created, the CronJob will be stored
within the job property of the service's top-level crons, allowing you to control the job
behaviour during runtime. The job object stores an unmodified
CronJob, which means you can freely use its
API:
start()Starts the job; if the job is already running, this will have no effect.stop()Stops the job; if the job is already stopped, this will have no effect.setTime()Modifies thecronTimeparameter for the job and must be a validCronTime(which can be obtained using the Mixin'sgetCronTime()method).lastDate()Provides the last execution date.nextDate()Provides the next date on which theonTickwill be called.nextDates(count)Provides the array of next dates on which theonTickwill be called, equal in length to thecountparameter.fireOnTick(): Allows a manual execution of theonTickfunction.addCallback(callback): Allows addition of the additional callbacks to theonTickfunction. Any additional callbacks will also receive the additional context from thecontextparameter, as well as Moleculer's service context.
Cron Patterns
In addition to the standard crontab specification, this mixin also utilises
the seconds parameter defined in cron.
Following patterns can be used to define the cronTime:
Extended pattern (with seconds)
<second> <minute> <hour> <day of month> <month> <day of week>
Standard pattern
<minute> <hour> <day of month> <month> <day of week>For each of the fields denoted by <field>, values can be defined as wildcards (*) allowing for
any value to match the pattern, ranges (1-3,5) specifying direct values, or ranges of values that
will match the pattern or steps (*/2) providing increments in which the pattern will be matched.
For example:
const cronTime = '*/30 * 9-17 * 1,3,6,12 1-5';
// Field Allowed Example Example description
//
// <second> 0-59 */30 Every 30 seconds
// <minute> 0-59 * Every minute
// <hour> 0-23 9-17 Every hour between 9 and 17 (9am to 5pm)
// <day of month> 1-31 * Every day of the month
// <month> 1-12 1,3,6,12 In January, March, June and December
// <day of week> 0-7 1-5 Between Monday and Friday.For a full specification of the crontab patterns, see crontab specification. You may also wish to use tools such as crontab.guru to assist you with the pattern definition, remembering that you may also define the seconds field.
TypeScript
Additional types are provided to facilitate integration within TypeScript projects. Below are the types you can import and extend your service interface with:
CronMixinConfigInterface of the configuration objects which need to be defined within the service's top-levelcronsproperty.CronMixinCronInterface of the object stored within service's top-levelcronsfollowing the initialisation.CronMixinSchemaInterface that can be used to extend themoleculer.ServiceSchemawhen using the mixin.CronMixinServiceInterface of the mixin that can be used to extend themoleculer.Servicewhen using the mixin.
For more details on using this mixing with TypeScript, please see the TypeScript example.