pl-sails-hook-jobs
Version:
Sails JS hook to add async background jobs, using agenda (https://www.npmjs.com/package/agenda).
178 lines (150 loc) • 5.4 kB
JavaScript
module.exports = function(sails) {
var Agenda = require('agenda'),
util = require('util'),
_ = require('lodash'),
os = require("os"),
agenda = new Agenda()
agenda.sails = sails;
var stopServer = function() {
agenda.stop(function() {
console.log("agenda stopped");
});
};
sails.on("lower", stopServer);
sails.on("lowering", stopServer);
// return hook
return {
// expose agenda in sails.hooks.jobs.agenda
jobs: agenda,
// Defaults config
defaults: {
jobs: {
"globalJobsObjectName": "Jobs",
"jobsDirectory": "api/jobs",
"startEvent" : 'start-agenda',
"db": {
"address" : "localhost:27017/jobs",
"collection" : "agendaJobs"
},
"name": os.hostname() + '-' + process.pid,
"processEvery": "1 minutes",
"maxConcurrency": 20,
"defaultConcurrency": 5,
"defaultLockLifetime": 10000,
}
},
// Runs automatically when the hook initializes
initialize: function (cb) {
var hook = this
, config = sails.config.jobs
// init agenda
sails.log.verbose("Create agenda with : ");
sails.log.verbose("DB Addr: " + config.db.address);
sails.log.verbose("DB Collection: " + config.db.collection);
sails.log.verbose("Name: " + config.name);
agenda
.database(config.db.address, config.db.collection)
.name(config.name)
.processEvery(config.processEvery)
.maxConcurrency(config.maxConcurrency)
.defaultConcurrency(config.defaultConcurrency)
.defaultLockLifetime(config.defaultLockLifetime)
global[config.globalJobsObjectName] = agenda;
// Enable jobs using coffeescript
try {
require('coffee-script/register');
} catch(e0) {
try {
var path = require('path');
var appPath = sails.config.appPath || process.cwd();
require(path.join(appPath, 'node_modules/coffee-script/register'));
} catch(e1) {
sails.log.verbose('Please run `npm install coffee-script` to use coffescript (skipping for now)');
}
}
// Find all jobs
var jobs = require('include-all')({
dirname : sails.config.appPath + '/' + config.jobsDirectory,
filter : /(.+Job).(?:js|coffee)$/,
excludeDirs : /^\.(git|svn)$/,
optional : true
});
// init jobs
agenda.on('ready', function() {
sails.log.verbose("Agenda ready !!");
hook.initJobs(jobs);
agenda.start();
sails.log.verbose("sails jobs started")
};
// Lets wait on some of the sails core hooks to
// finish loading before we load our hook
// that talks about cats.
var eventsToWaitFor = [];
if (sails.hooks.orm)
eventsToWaitFor.push('hook:orm:loaded');
if (sails.hooks.pubsub)
eventsToWaitFor.push('hook:pubsub:loaded');
sails.on(config.startEvent, function(){
});
sails.after(eventsToWaitFor, function(){
// if (jobs.length > 0) {
// start agenda
//agenda.start();
//sails.log.verbose("sails jobs started")
// }
// Now we will return the callback and our hook
// will be usable.
return cb();
});
},
/**
* Function that initialize jobs
*/
initJobs: function(jobs, namespace) {
var hook = this
if (!namespace) namespace = "jobs";
sails.log.verbose("looking for job in " + namespace + "... ")
_.forEach(jobs, function(job, name){
if (typeof job === 'function') {
var log = ""
, _job = job(agenda)
, _dn = namespace + "." + name
, _name = _job.name || _dn.substr(_dn.indexOf('.') +1);
if (_job.disabled) {
log += "-> Disabled Job '" + _name + "' found in '" + namespace + "." + name + "'.";
} else {
var options = (typeof _job.options === 'object')?_job.options:{}
, freq = _job.frequency
, error = false;
if (typeof _job.run === "function")
agenda.define(_name, options, _job.run);
log += "-> Job '" + _name + "' found in '" + namespace + "." + name + "', defined in agenda";
if (typeof freq === 'string') {
freq = freq.trim().toLowerCase();
if (freq.indexOf('every') == 0) {
var interval = freq.substr(6).trim();
agenda.every(interval, _name, _job.data);
log += " and will run " + freq;
} else if (freq.indexOf('schedule') == 0) {
var when = freq.substr(9).trim();
agenda.schedule(when, _name, _job.data);
log += " and scheduled " + when;
} else if (freq === 'now') {
agenda.now(_name, _job.data);
log += " and started";
} else {
error = true;
log += " but frequency is not supported";
}
}
}
log += ".";
if (error) sails.log.error(log);
else sails.log.verbose(log);
} else {
hook.initJobs(job, namespace + "." + name);
}
})
}
}
};