{"size": 2485, "ext": "js", "max_stars_repo_path": "lib/plugins/jobLock.js", "max_stars_repo_name": "jahraphael/node-resque", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "lib/plugins/jobLock.js", "max_issues_repo_name": "jahraphael/node-resque", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "lib/plugins/jobLock.js", "max_forks_repo_name": "jahraphael/node-resque", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 25.618556701, "max_line_length": 112, "alphanum_fraction": 0.6494969819}
// 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;
