Simple package with similar API to native setTimeout
and setInterval
methods, but synced between all running Meteor (NodeJS) instances.
Multi-instance task manager for Node.js. This package has the support of cluster or multi-thread NodeJS instances. This package will help you to make sure only one process of each task is running.
This is a server-only package.
meteor add ostrio:cron-jobs
Looking for NPM version? - Go to JoSk package
import { CRONjob } from 'meteor/ostrio:cron-jobs';
Error: Can't wait without a fiber
Can be easily solved via "bounding to Fiber":
const bound = Meteor.bindEnvironment((callback) => {
callback();
});
const db = Collection.rawDatabase();
const CRON = new CRONjob({db: db});
const task = (ready) => {
bound(() => {
ready();
});
};
CRON.setInterval(task, 60*60*1000, 'task');
new CRONjob({opts})
:
opts.db
{Object} - [Required] Connection to MongoDBopts.prefix
{String} - [Optional] use to create multiple named instancesopts.autoClear
{Boolean} - [Optional] Remove (Clear) obsolete tasks (any tasks which are not found in the instance memory (runtime), but exists in the database). Obsolete tasks may appear in cases when it wasn't cleared from the database on process shutdown, and/or was removed/renamed in the app. Obsolete tasks may appear if multiple app instances running different codebase within the same database, and the task may not exist on one of the instances. Default:false
opts.resetOnInit
{Boolean} - [Optional] make sure all old tasks is completed before set new one. Useful when you run only one instance of app, or multiple app instances on one machine, in case machine was reloaded during running task and task is unfinishedopts.zombieTime
{Number} - [Optional] time in milliseconds, after this time - task will be interpreted as "zombie". This parameter allows to rescue task from "zombie mode" in case whenready()
wasn't called, exception during runtime was thrown, or caused by bad logic. WhereresetOnInit
makes sure task is done on startup, butzombieTime
doing the same function but during runtime. Default value is900000
(15 minutes)opts.onError
{Function} - [Optional] Informational hook, called instead of throwing exceptions. Default:false
. Called with two arguments:title
{String}details
{Object}details.description
{String}details.error
{Mix}details.uid
{String} - Internaluid
, suitable for.clearInterval()
and.clearTimeout()
opts.onExecuted
{Function} - [Optional] Informational hook, called when task is finished. Default:false
. Called with two arguments:uid
{String} -uid
passed into.setImmediate()
,.setTimeout()
, orsetInterval()
methodsdetails
{Object}details.uid
{String} - Internaluid
, suitable for.clearInterval()
and.clearTimeout()
details.date
{Date} - Execution timestamp as JS Datedetails.timestamp
{Number} - Execution timestamp as unix Number
// Meteor.users.rawDatabase() is available in most Meteor setups
// If this is not your case, you can use `rawDatabase` form any other collection
const db = Meteor.users.rawDatabase();
const CRON = new CRONjob({db: db});
Note: This library relies on job ID, so you can not pass the same job (with same ID). Always use different uid
, even for the same task:
const task = function (ready) {
//...some code here
ready();
};
CRON.setInterval(task, 60*60*1000, 'task-1000');
CRON.setInterval(task, 60*60*2000, 'task-2000');
Passing arguments (not really fancy solution, sorry):
const CRON = new CRONjob({db: db});
const globalVar = 'Some top level or env.variable (can be changed over time)';
const task = function (arg1, arg2, ready) {
//...some code here
ready();
};
const taskB = function (ready) {
task(globalVar, 'b', ready);
};
const task1 = function (ready) {
task(1, globalVar, ready);
};
CRON.setInterval(taskB, 60*60*1000, 'taskB');
CRON.setInterval(task1, 60*60*1000, 'task1');
Note: To clean up old tasks via MongoDB use next query pattern:
// Run directly in MongoDB console:
db.getCollection('__JobTasks__').remove({});
// If you're using multiple CRONjob instances with prefix:
db.getCollection('__JobTasks__PrefixHere').remove({});
func
{Function} - Function to call by scheduledelay
{Number} - Delay for first run and interval between further executions in millisecondsuid
{String} - Unique app-wide task id
Set task into interval execution loop. ready()
is passed as third argument into function.
In this example, next task will not be scheduled until the current is ready:
const syncTask = function (ready) {
//...run sync code
ready();
};
const asyncTask = function (ready) {
asyncCall(function () {
//...run more async code
ready();
});
};
CRON.setInterval(syncTask, 60*60*1000, 'syncTask');
CRON.setInterval(asyncTask, 60*60*1000, 'asyncTask');
In this example, next task will not wait for the current task to finish:
const syncTask = function (ready) {
ready();
//...run sync code
};
const asyncTask = function (ready) {
ready();
asyncCall(function () {
//...run more async code
});
};
CRON.setInterval(syncTask, 60*60*1000, 'syncTask');
CRON.setInterval(asyncTask, 60*60*1000, 'asyncTask');
In this example, we're assuming to have long running task, executed in a loop without delay, but after full execution:
const longRunningAsyncTask = function (ready) {
asyncCall(function (error, result) {
if(error){
ready(); // <-- Always run `ready()`, even if call was unsuccessful
} else {
anotherCall(result.data, ['param'], function (error, response) {
waitForSomethingElse(response, function () {
ready(); // <-- End of full execution
});
});
}
});
};
CRON.setInterval(longRunningAsyncTask, 0, 'longRunningAsyncTask');
func
{Function} - Function to call on scheduledelay
{Number} - Delay in millisecondsuid
{String} - Unique app-wide task id
Set task into timeout execution. setTimeout
is useful for cluster - when you need to make sure task was executed only once.
ready()
is passed as third argument into function.
const syncTask = function (ready) {
//...run sync code
ready();
};
const asyncTask = function (ready) {
asyncCall(function () {
//...run more async code
ready();
});
};
CRON.setTimeout(syncTask, 60*60*1000, 'syncTask');
CRON.setTimeout(asyncTask, 60*60*1000, 'asyncTask');
func
{Function} - Function to executeuid
{String} - Unique app-wide task id
Immediate execute the function, and only once. setImmediate
is useful for cluster - when you need to execute function immediately and only once across all servers. ready()
is passed as the third argument into the function.
const syncTask = function (ready) {
//...run sync code
ready();
};
const asyncTask = function (ready) {
asyncCall(function () {
//...run more async code
ready();
});
};
CRON.setImmediate(syncTask, 'syncTask');
CRON.setImmediate(asyncTask, 'asyncTask');
Cancel (abort) current interval timer.
const timer = CRON.setInterval(func, 34789, 'unique-taskid');
CRON.clearInterval(timer);
Cancel (abort) current timeout timer.
const timer = CRON.setTimeout(func, 34789, 'unique-taskid');
CRON.clearTimeout(timer);
This project wouldn't be possible without ostr.io.
Using ostr.io you are not only protecting domain names, monitoring websites and servers, using Prerendering for better SEO of your JavaScript website, but support our Open Source activity, and great packages like this one could be available for free.