node-resque
Version:
an opinionated implementation of resque in node
97 lines (84 loc) • 2.48 kB
JavaScript
// If a job with the same name, queue, and args is already running, put this job back in the queue and try later
var jobLock = function(worker, func, queue, job, args, options){
var self = this;
self.name = 'jobLock';
self.worker = worker;
self.queue = queue;
self.func = func;
self.job = job;
self.args = args;
self.options = options;
}
////////////////////
// PLUGIN METHODS //
////////////////////
jobLock.prototype.before_enqueue = function(callback){
// console.log("** before_enqueue")
callback(null, true);
}
jobLock.prototype.after_enqueue = function(callback){
// console.log("** after_enqueue")
callback(null, true);
}
jobLock.prototype.before_perform = function(callback){
// console.log("** before_perform")
var self = this;
var key = self.key();
var now = Math.round(new Date().getTime() / 1000);
var timeout = now + self.lock_timeout() + 1;
self.worker.connection.redis.setnx(key, timeout, function(err, setCallback){
if(setCallback === true || setCallback === 1){
self.worker.connection.redis.expire(key, self.lock_timeout());
callback(null, true);
}else{
self.reEnqueue(function(){
callback(null, false);
});
}
});
}
jobLock.prototype.after_perform = function(callback){
// console.log("** after_perform")
var self = this;
var key = self.key();
self.worker.connection.redis.del(key, function(err){
callback(null, true);
});
}
/////////////
// HELPERS //
/////////////
jobLock.prototype.reEnqueue = function(callback){
var self = this;
setTimeout(function(){
self.worker.queueObject.enqueue(self.queue, self.func, self.args, function(){
callback();
});
}, self.enqueue_timeout() );
}
jobLock.prototype.lock_timeout = function(){
var self = this;
if (self.options.lock_timeout != null){
return self.options.lock_timeout;
}else{
return 3600; // in seconds
}
}
jobLock.prototype.enqueue_timeout = function(){
var self = this;
if (self.options.enqueue_timeout != null){
return self.options.enqueue_timeout;
}else{
return 1001; // in ms
}
}
jobLock.prototype.key = function(){
var self = this;
if (self.options.key != null){
return typeof self.options.key === 'function' ? self.options.key.apply(this) : self.options.key;
}else{
var flattenedArgs = JSON.stringify(self.args);
return self.worker.connection.key('workerslock', self.func, self.queue, flattenedArgs);
}
}
exports.jobLock = jobLock;