nyx_schedule
Version:
nyx任务调度
151 lines (130 loc) • 3.73 kB
JavaScript
/* global process */
/** @package
job.js
21/04/2015 NF Removed database code. ie. From Job.remove()
Last change: NF 21/04/2015 1:20:47 PM
*/
var humanInterval = require('human-interval'),
CronTime = require('cron').CronTime,
date = require('date.js'),
moment = require('moment-timezone');
var Promise = require("bluebird");
module.exports = Job;
function Job(schedule , attrs) {
this.scheduler = schedule;
this.attrs = attrs;
};
Job.prototype.toJSON = function () { // create a persistable Mongo object -RR
var self = this,
attrs = self.attrs || {};
var result = {};
for (var prop in attrs) {
if (attrs.hasOwnProperty(prop)) {
result[prop] = attrs[prop];
}
}
var dates = ['lastRunAt', 'lastFinishedAt', 'nextRunAt', 'failedAt', 'lockedAt'];
dates.forEach(function (d) {
if (result[d]) {
result[d] = new Date(result[d]);
}
});
return result;
};
/**
* 计算job的下次执行时间
*/
Job.prototype.computeNextRunAt = function () {
var start = this.attrs.start; //任务开始时间
var end = this.attrs.end; //任务结束时间
var interval = this.attrs.interval; //任务间隔
//var timezone = this.attrs.repeatTimezone; //时区
if(!this.attrs.nextRunAt){
this.attrs.nextRunAt = date(interval+" second from" , start);
}else if(end && this.attrs.nextRunAt > end){
this.disable();
}else{
this.attrs.nextRunAt = date(interval+" second from now");
}
};
Job.prototype.disable = function () {
this.attrs.disabled = 0;
return this;
};
Job.prototype.enable = function () {
this.attrs.disabled = 1;
return this;
};
/**
* 修改下次执行时间
*/
Job.prototype.schedule = function (time) {
this._scheduled = true;
this.attrs.nextRunAt = (time instanceof Date) ? time : date(time);
return this;
};
/**
* 设置优先级
*/
Job.prototype.priority = function (priority) {
this.attrs.priority = priority;
return this;
};
Job.prototype.fail = function (reason) {
if (reason instanceof Error) {
reason = reason.message;
}
this.attrs.failReason = reason;
this.attrs.failCount = (this.attrs.failCount || 0) + 1;
this.attrs.failedAt = new Date();
return this;
};
/**
* 运行job
* @param cb 执行完毕后的回调函数
*/
Job.prototype.run = function (cb) {
var self = this,
scheduler = self.scheduler;
var setImmediate = setImmediate || process.nextTick;
setImmediate(function () {
self.attrs.lastRunAt = new Date();
scheduler.execJob(self).then(function(){
self.computeNextRunAt();
self.attrs.lastFinishedAt = new Date();
self.attrs.lockedAt = null;
self.save().finally(function(){
cb(null , self);
})
}).catch(function(err){
self.computeNextRunAt();
self.attrs.lastFinishedAt = new Date();
self.attrs.lockedAt = null;
self.fail(err);
self.save().finally(function(){
cb(err , self);
})
})
});
};
/**
* 判断job是否在运行中
*/
Job.prototype.isRunning = function () {
if (!this.attrs.lastRunAt) return false;
if (!this.attrs.lastFinishedAt) return true;
if (this.attrs.lockedAt && this.attrs.lastRunAt.getTime() > this.attrs.lastFinishedAt.getTime()) {
return true;
}
return false;
};
/**
* 保存job入库
*/
Job.prototype.save = function () {
return this.scheduler.saveJob(this);
};
Job.prototype.touch = function (cb) {
this.attrs.lockedAt = new Date();
this.save(cb);
};