cron
Advanced tools
Comparing version 1.1.1 to 1.2.0
182
lib/cron.js
@@ -1,9 +0,18 @@ | ||
var exports, | ||
(function (root, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
define(['moment-timezone'], factory); | ||
} else if (typeof exports === 'object') { | ||
module.exports = factory(require('moment-timezone'), require('child_process')); | ||
} else { | ||
root.Cron = factory(root.moment); | ||
} | ||
}(this, function (moment, child_process) { | ||
var exports = {}, | ||
timeUnits = ['second', 'minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek'], | ||
spawn = require('child_process').spawn, | ||
moment = require('moment-timezone'); | ||
spawn = child_process && child_process.spawn; | ||
function CronTime(source, zone) { | ||
this.source = source; | ||
if (zone) { | ||
@@ -27,4 +36,3 @@ if (moment.tz.names().indexOf(zone) === -1) { | ||
this._parse(); | ||
if (!this._verifyParse()) | ||
throw Error("Could not verify a valid date. Please verify your parameters."); | ||
this._verifyParse(); | ||
} | ||
@@ -94,8 +102,5 @@ } | ||
if (!ok) { | ||
console.error("Month '" + m + "' is limited to '" + con + "' days."); | ||
return false; | ||
console.warn('Month \'' + m + '\' is limited to \'' + con + '\' days.'); | ||
} | ||
} | ||
return true; | ||
}, | ||
@@ -106,3 +111,3 @@ | ||
*/ | ||
sendAt: function() { | ||
sendAt: function(i) { | ||
var date = this.realDate ? this.source : moment(); | ||
@@ -127,5 +132,17 @@ // Set the timezone if given (http://momentjs.com/timezone/docs/#/using-timezones/parsing-in-zone/) | ||
date = this._getNextDateFrom(date); | ||
return date; | ||
//If the i argument is not given, return the next send time | ||
if(isNaN(i) || i < 0){ | ||
date = this._getNextDateFrom(date); | ||
return date; | ||
} | ||
//Else return the next i send times | ||
else{ | ||
var dates = []; | ||
for(;i>0;i--){ | ||
date = this._getNextDateFrom(date); | ||
dates.push(moment(date)); | ||
if(i>1) date.add(1,'s'); | ||
} | ||
return dates; | ||
} | ||
}, | ||
@@ -163,11 +180,11 @@ | ||
if (date.toString() == 'Invalid date') { | ||
console.log("ERROR: You specified an invalid date."); | ||
console.log('ERROR: You specified an invalid date.'); | ||
return date; | ||
} | ||
if (this.realDate && start < new Date()) | ||
console.log("WARNING: Date in past. Will never be fired."); | ||
console.log('WARNING: Date in past. Will never be fired.'); | ||
if (this.realDate) return date; | ||
//sanity check | ||
while (1) { | ||
while (true) { | ||
var diff = date - start, | ||
@@ -244,4 +261,3 @@ origDate = new Date(date); | ||
_findDST: function(date) { | ||
var newDate = moment(date), | ||
addSeconds = 1; | ||
var newDate = moment(date); | ||
while (newDate <= date) | ||
@@ -303,44 +319,45 @@ newDate.add(1, 's'); | ||
_parseField: function(field, type, constraints) { | ||
var rangePattern = /^(\d+)(?:-(\d+))?(?:\/(\d+))?$/g, | ||
typeObj = this[type], | ||
diff, pointer, | ||
low = constraints[0], | ||
high = constraints[1]; | ||
var rangePattern = /^(\d+)(?:-(\d+))?(?:\/(\d+))?$/g, | ||
typeObj = this[type], | ||
pointer, | ||
low = constraints[0], | ||
high = constraints[1]; | ||
// * is a shortcut to [lower-upper] range | ||
field = field.replace(/\*/g, low + '-' + high); | ||
// * is a shortcut to [lower-upper] range | ||
field = field.replace(/\*/g, low + '-' + high); | ||
//commas separate information, so split based on those | ||
var allRanges = field.split(','); | ||
//commas separate information, so split based on those | ||
var allRanges = field.split(','); | ||
for (var i = 0; i < allRanges.length; i++) { | ||
if (allRanges[i].match(rangePattern)) { | ||
allRanges[i].replace(rangePattern, function($0, lower, upper, step) { | ||
step = parseInt(step) || 1; | ||
// Positive integer higher than constraints[0] | ||
lower = Math.min(Math.max(low, ~~Math.abs(lower)), high); | ||
for (var i = 0; i < allRanges.length; i++) { | ||
if (allRanges[i].match(rangePattern)) { | ||
allRanges[i].replace(rangePattern, function($0, lower, upper, step) { | ||
step = parseInt(step) || 1; | ||
// Positive integer higher than constraints[0] | ||
lower = Math.min(Math.max(low, ~~Math.abs(lower)), high); | ||
// Positive integer lower than constraints[1] | ||
upper = upper ? Math.min(high, ~~Math.abs(upper)) : lower; | ||
// Positive integer lower than constraints[1] | ||
upper = upper ? Math.min(high, ~~Math.abs(upper)) : lower; | ||
// Count from the lower barrier to the upper | ||
pointer = lower; | ||
// Count from the lower barrier to the upper | ||
pointer = lower; | ||
do { | ||
typeObj[pointer] = true | ||
pointer += step; | ||
} while (pointer <= upper); | ||
}); | ||
} else { | ||
throw new Error('Field (' + field + ') cannot be parsed'); | ||
} | ||
} | ||
} | ||
do { | ||
typeObj[pointer] = true | ||
pointer += step; | ||
} while (pointer <= upper); | ||
}); | ||
} else { | ||
throw new Error('Field (' + field + ') cannot be parsed'); | ||
} | ||
} | ||
} | ||
}; | ||
function command2function(cmd) { | ||
var command, args; | ||
switch (typeof cmd) { | ||
case 'string': | ||
var args = cmd.split(' '); | ||
var command = args.shift(); | ||
args = cmd.split(' '); | ||
command = args.shift(); | ||
@@ -350,5 +367,5 @@ cmd = spawn.bind(undefined, command, args); | ||
case 'object': | ||
var command = cmd && cmd.command; | ||
command = cmd && cmd.command; | ||
if (command) { | ||
var args = cmd.args; | ||
args = cmd.args; | ||
var options = cmd.options; | ||
@@ -366,3 +383,3 @@ | ||
var _cronTime = cronTime; | ||
if (typeof cronTime != "string" && arguments.length == 1) { | ||
if (typeof cronTime != 'string' && arguments.length == 1) { | ||
//crontime is an object... | ||
@@ -412,2 +429,6 @@ onTick = cronTime.onTick; | ||
CronJob.prototype.nextDates = function(i) { | ||
return this.cronTime.sendAt(i); | ||
} | ||
var start = function() { | ||
@@ -420,5 +441,11 @@ if (this.running) return; | ||
var remaining = 0; | ||
var startTime; | ||
if (this.cronTime.realDate) this.runOnce = true; | ||
function _setTimeout(timeout) { | ||
startTime = Date.now(); | ||
self._timeout = setTimeout(callbackWrapper, timeout); | ||
} | ||
// The callback wrapper checks if it needs to sleep another period or not | ||
@@ -428,3 +455,14 @@ // and does the real callback logic when it's time. | ||
function callbackWrapper() { | ||
var diff = startTime + timeout - Date.now(); | ||
if (diff > 0) { | ||
var newTimeout = self.cronTime.getTimeout(); | ||
if (newTimeout > diff) { | ||
newTimeout = diff; | ||
} | ||
remaining += newTimeout; | ||
} | ||
// If there is sleep time remaining, calculate how long and go to sleep | ||
@@ -445,3 +483,3 @@ // again. This processing might make us miss the deadline by a few ms | ||
self._timeout = setTimeout(callbackWrapper, timeout); | ||
_setTimeout(timeout); | ||
} else { | ||
@@ -472,3 +510,3 @@ | ||
this._timeout = setTimeout(callbackWrapper, timeout); | ||
_setTimeout(timeout); | ||
} else { | ||
@@ -495,21 +533,23 @@ this.stop(); | ||
if (exports) { | ||
exports.job = function(cronTime, onTick, onComplete) { | ||
return new CronJob(cronTime, onTick, onComplete); | ||
} | ||
exports.job = function(cronTime, onTick, onComplete) { | ||
return new CronJob(cronTime, onTick, onComplete); | ||
} | ||
exports.time = function(cronTime, timeZone) { | ||
return new CronTime(cronTime, timeZone); | ||
} | ||
exports.time = function(cronTime, timeZone) { | ||
return new CronTime(cronTime, timeZone); | ||
} | ||
exports.sendAt = function(cronTime) { | ||
return exports.time(cronTime).sendAt(); | ||
} | ||
exports.sendAt = function(cronTime) { | ||
return exports.time(cronTime).sendAt(); | ||
} | ||
exports.timeout = function(cronTime) { | ||
return exports.time(cronTime).getTimeout(); | ||
} | ||
exports.timeout = function(cronTime) { | ||
return exports.time(cronTime).getTimeout(); | ||
} | ||
exports.CronJob = CronJob; | ||
exports.CronTime = CronTime; | ||
} | ||
exports.CronJob = CronJob; | ||
exports.CronTime = CronTime; | ||
return exports; | ||
})); |
{ | ||
"name": "cron", | ||
"description": "Cron jobs for your node", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"author": "Nick Campbell <nicholas.j.campbell@gmail.com> (http://github.com/ncb000gt)", | ||
@@ -6,0 +6,0 @@ "bugs" : { |
@@ -45,2 +45,3 @@ node-cron | ||
Note - You need to explictly start a job in order to make it run. This gives a little more control over running your jobs. | ||
@@ -47,0 +48,0 @@ Available Cron patterns: |
@@ -38,2 +38,21 @@ var chai = require('chai'), | ||
it('should fire every 60 min', function () { | ||
var m60 = 60 * 60 * 1000; | ||
var clock = sinon.useFakeTimers(); | ||
var l = []; | ||
var job = new cron.CronJob('00 30 * * * *', function () { | ||
l.push(Math.floor(Date.now() / 60000)); | ||
},null,true); | ||
clock.tick(m60 * 10); | ||
expect(l.length).to.eql(10); | ||
for (var i = 0; i < l.length; i++) { | ||
expect(l[i] % 30).to.eql(0); | ||
} | ||
job.stop(); | ||
clock.restore(); | ||
}); | ||
it('should use standard cron no-seconds syntax (* * * * *)', function() { | ||
@@ -316,3 +335,3 @@ var clock = sinon.useFakeTimers(); | ||
t.add(1, 's'); | ||
// Run a job designed to be executed at a given | ||
// Run a job designed to be executed at a given | ||
// time in `zone`, making sure that it is a different | ||
@@ -529,3 +548,18 @@ // hour than local time. | ||
it('should not fire if time was adjusted back', function() { | ||
var c = 0; | ||
var clock = sinon.useFakeTimers('setTimeout'); | ||
var job = new cron.CronJob('0 * * * * *', function() { | ||
c++; | ||
}, null, true); | ||
clock.tick(60000); | ||
expect(c).to.eql(0); | ||
clock.restore(); | ||
job.stop(); | ||
}); | ||
it('should run every second monday'); | ||
}); |
@@ -43,3 +43,2 @@ var chai = require('chai'), | ||
it('should test standard cron format (8 8 8 8 5)', function() { | ||
var now = Date.now(); | ||
var standard = new cron.CronTime('8 8 8 8 5'); | ||
@@ -178,13 +177,2 @@ var extended = new cron.CronTime('0 8 8 8 8 5'); | ||
it('should test < constraints day of month', function() { | ||
var ltm = [1, 3, 5, 8, 10]; | ||
for (var i = 0; i < ltm.length; i++) { | ||
(function(m) { | ||
expect(function() { | ||
var ct = new cron.CronTime('0 0 0 33 ' + m + ' *'); | ||
}).to.throw(Error); | ||
})(ltm[i]); | ||
} | ||
}); | ||
it('should test next month selection'); | ||
@@ -191,0 +179,0 @@ |
40044
12
1113
197