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.
To install the package, run the following in your Moleculer project:
npm install @marceliwac/moleculer-cron
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;
}
}
}
};
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:
// 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;
}
-
name
Defines the name that can be used to find the job usinggetCron()
function. By default, a UUID v4 will be provided. -
cronTime
Specifies 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. -
onTick
Function to be executed at the specifiedcronTime
. This function will receive additional context from thecontext
parameter, as well as Moleculer's service context. -
onInitialise
Function which will be executed before the cron job is created. This function will receive additional context from thecontext
parameter, as well as Moleculer's service context. -
onStart
Function which will be executed after the cron job is created. This function will receive additional context from thecontext
parameter, as well as Moleculer's service context. -
onStop
Function which will be executed after the cron job is stopped, or after the service stops. This function will receive additional context from thecontext
parameter, as well as Moleculer's service context. -
onComplete
Similarly 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 theonTick
function allowing you to manually call it with everyonTick
call. UnlikeonStop
, this function will not receive any additional context when called when the job stops. It could however be called with any context (including thecontext
parameter, as well as the Moleculer's service context) when called with everyonTick
(for more details, see examples). -
start
Defines 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
. -
runOnInit
Specifies whether theonTick
should be fired immediately following the job creation, regardless of thecronTime
orstart
parameter. Following this initial call, all future calls will respect thecronTime
andstart
parameters and only run at specified times if the job is started. -
context
Allows 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
. -
timeZone
Specifies the timezone that should be used for the cronTime configuration. This is particularly important when thecronTime
defines a specific hour, day, month or day of the week, or a specific range for any of those values. ConfiguringtimeZone
andutcOffset
is mutually exclusive. -
utcOffset
Alternative to thetimeZone
which allows for specifying the offset to the UTC timezone in minutes. Both positive and negative values can be used (e.g.60
would be UTC+1,-120
would be UTC-2). ConfiguringutcOffset
andtimeZone
is mutually exclusive. -
unrefTimeout
Specifies 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
function
s, which can inherit the context, rather than arrow functions / lambdas (() => {}
).
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.
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 thecronTime
parameter 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 theonTick
will be called. -
nextDates(count)
Provides the array of next dates on which theonTick
will be called, equal in length to thecount
parameter. -
fireOnTick()
: Allows a manual execution of theonTick
function. -
addCallback(callback)
: Allows addition of the additional callbacks to theonTick
function. Any additional callbacks will also receive the additional context from thecontext
parameter, as well as Moleculer's service context.
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.
Additional types are provided to facilitate integration within TypeScript projects. Below are the types you can import and extend your service interface with:
-
CronMixinConfig
Interface of the configuration objects which need to be defined within the service's top-levelcrons
property. -
CronMixinCron
Interface of the object stored within service's top-levelcrons
following the initialisation. -
CronMixinSchema
Interface that can be used to extend themoleculer.ServiceSchema
when using the mixin. -
CronMixinService
Interface of the mixin that can be used to extend themoleculer.Service
when using the mixin.
For more details on using this mixing with TypeScript, please see the TypeScript example.