node-schedule 1.2.4 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -10
- package/lib/schedule.js +25 -16
- package/package.json +2 -2
- package/test/cancel-long-running-jobs.js +24 -0
- package/test/job-test.js +61 -0
- package/test/start-end-test.js +16 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ The cron format consists of:
|
|
|
58
58
|
```
|
|
59
59
|
* * * * * *
|
|
60
60
|
┬ ┬ ┬ ┬ ┬ ┬
|
|
61
|
-
│ │ │ │ │
|
|
61
|
+
│ │ │ │ │ │
|
|
62
62
|
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
|
|
63
63
|
│ │ │ │ └───── month (1 - 12)
|
|
64
64
|
│ │ │ └────────── day of month (1 - 31)
|
|
@@ -89,6 +89,13 @@ var j = schedule.scheduleJob('0 17 ? * 0,4-6', function(){
|
|
|
89
89
|
|
|
90
90
|
Execute a cron job every 5 Minutes = */5 * * * *
|
|
91
91
|
|
|
92
|
+
You can also get when it is scheduled to run for every invocation of the job:
|
|
93
|
+
```js
|
|
94
|
+
var j = schedule.scheduleJob('0 1 * * *', function(fireDate){
|
|
95
|
+
console.log('This job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date());
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
This is useful when you need to check if there is a delay of the job invocation when the system is busy, or save a record of all invocations of a job for audit purpose.
|
|
92
99
|
#### Unsupported Cron Features
|
|
93
100
|
|
|
94
101
|
Currently, `W` (nearest weekday), `L` (last day of month/week), and `#` (nth weekday
|
|
@@ -158,13 +165,13 @@ var j = schedule.scheduleJob(rule, function(){
|
|
|
158
165
|
|
|
159
166
|
#### RecurrenceRule properties
|
|
160
167
|
|
|
161
|
-
- `second`
|
|
162
|
-
- `minute`
|
|
163
|
-
- `hour`
|
|
164
|
-
- `date`
|
|
165
|
-
- `month`
|
|
168
|
+
- `second (0-59)`
|
|
169
|
+
- `minute (0-59)`
|
|
170
|
+
- `hour (0-23)`
|
|
171
|
+
- `date (1-31)`
|
|
172
|
+
- `month (0-11)`
|
|
166
173
|
- `year`
|
|
167
|
-
- `dayOfWeek`
|
|
174
|
+
- `dayOfWeek (0-6) Starting with Sunday`
|
|
168
175
|
|
|
169
176
|
> **Note**: It's worth noting that the default value of a component of a recurrence rule is
|
|
170
177
|
> `null` (except for second, which is 0 for familiarity with cron). *If we did not
|
|
@@ -197,11 +204,11 @@ var j = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 * * *
|
|
|
197
204
|
|
|
198
205
|
### Handle Jobs and Job Invocations
|
|
199
206
|
|
|
200
|
-
There are some function to get
|
|
207
|
+
There are some function to get information for a Job and to handle the Job and
|
|
201
208
|
Invocations.
|
|
202
209
|
|
|
203
210
|
|
|
204
|
-
#### job.cancel(
|
|
211
|
+
#### job.cancel(reschedule)
|
|
205
212
|
You can invalidate any job with the `cancel()` method:
|
|
206
213
|
|
|
207
214
|
```js
|
|
@@ -210,7 +217,7 @@ j.cancel();
|
|
|
210
217
|
All planned invocations will be canceled. When you set the parameter ***reschedule***
|
|
211
218
|
to true then the Job is newly scheduled afterwards.
|
|
212
219
|
|
|
213
|
-
#### job.cancelNext(
|
|
220
|
+
#### job.cancelNext(reschedule)
|
|
214
221
|
This method invalidates the next planned invocation or the job.
|
|
215
222
|
When you set the parameter ***reschedule*** to true then the Job is newly scheduled
|
|
216
223
|
afterwards.
|
package/lib/schedule.js
CHANGED
|
@@ -90,7 +90,7 @@ function Job(name, job, callback) {
|
|
|
90
90
|
|
|
91
91
|
cancelInvocation(inv);
|
|
92
92
|
|
|
93
|
-
if (reschedule && inv.recurrenceRule.recurs) {
|
|
93
|
+
if (reschedule && (inv.recurrenceRule.recurs || inv.recurrenceRule.next)) {
|
|
94
94
|
newInv = scheduleNextRecurrence(inv.recurrenceRule, this, inv.fireDate, inv.endDate);
|
|
95
95
|
if (newInv !== null) {
|
|
96
96
|
newInvs.push(newInv);
|
|
@@ -125,7 +125,7 @@ function Job(name, job, callback) {
|
|
|
125
125
|
|
|
126
126
|
cancelInvocation(nextInv);
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
if (reschedule && (nextInv.recurrenceRule.recurs || nextInv.recurrenceRule.next)) {
|
|
129
129
|
newInv = scheduleNextRecurrence(nextInv.recurrenceRule, this, nextInv.fireDate, nextInv.endDate);
|
|
130
130
|
if (newInv !== null) {
|
|
131
131
|
this.trackInvocation(newInv);
|
|
@@ -167,12 +167,12 @@ function Job(name, job, callback) {
|
|
|
167
167
|
|
|
168
168
|
util.inherits(Job, events.EventEmitter);
|
|
169
169
|
|
|
170
|
-
Job.prototype.invoke = function() {
|
|
170
|
+
Job.prototype.invoke = function(fireDate) {
|
|
171
171
|
if (typeof this.job == 'function') {
|
|
172
172
|
this.setTriggeredJobs(this.triggeredJobs() + 1);
|
|
173
|
-
this.job();
|
|
173
|
+
this.job(fireDate);
|
|
174
174
|
} else {
|
|
175
|
-
this.job.execute();
|
|
175
|
+
this.job.execute(fireDate);
|
|
176
176
|
}
|
|
177
177
|
};
|
|
178
178
|
|
|
@@ -188,10 +188,14 @@ Job.prototype.schedule = function(spec) {
|
|
|
188
188
|
var end;
|
|
189
189
|
var tz;
|
|
190
190
|
|
|
191
|
+
// save passed-in value before 'spec' is replaced
|
|
192
|
+
if (typeof spec === 'object' && 'tz' in spec) {
|
|
193
|
+
tz = spec.tz;
|
|
194
|
+
}
|
|
195
|
+
|
|
191
196
|
if (typeof spec === 'object' && spec.rule) {
|
|
192
197
|
start = spec.start || undefined;
|
|
193
198
|
end = spec.end || undefined;
|
|
194
|
-
tz = spec.tz;
|
|
195
199
|
spec = spec.rule;
|
|
196
200
|
|
|
197
201
|
if (start) {
|
|
@@ -398,6 +402,11 @@ RecurrenceRule.prototype.isValid = function() {
|
|
|
398
402
|
};
|
|
399
403
|
|
|
400
404
|
RecurrenceRule.prototype.nextInvocationDate = function(base) {
|
|
405
|
+
var next = this._nextInvocationDate(base);
|
|
406
|
+
return next ? next.toDate() : null;
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
RecurrenceRule.prototype._nextInvocationDate = function(base) {
|
|
401
410
|
base = ((base instanceof CronDate) || (base instanceof Date)) ? base : (new Date());
|
|
402
411
|
if (!this.recurs) {
|
|
403
412
|
return null;
|
|
@@ -464,7 +473,7 @@ RecurrenceRule.prototype.nextInvocationDate = function(base) {
|
|
|
464
473
|
break;
|
|
465
474
|
}
|
|
466
475
|
|
|
467
|
-
return next
|
|
476
|
+
return next;
|
|
468
477
|
};
|
|
469
478
|
|
|
470
479
|
function recurMatch(val, matcher) {
|
|
@@ -491,15 +500,15 @@ function recurMatch(val, matcher) {
|
|
|
491
500
|
|
|
492
501
|
/* Date-based scheduler */
|
|
493
502
|
function runOnDate(date, job) {
|
|
494
|
-
var now =
|
|
503
|
+
var now = Date.now();
|
|
495
504
|
var then = date.getTime();
|
|
496
505
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
506
|
+
return lt.setTimeout(function() {
|
|
507
|
+
if (then > Date.now())
|
|
508
|
+
runOnDate(date, job);
|
|
509
|
+
else
|
|
510
|
+
job();
|
|
511
|
+
}, (then < now ? 0 : then - now));
|
|
503
512
|
}
|
|
504
513
|
|
|
505
514
|
var invocations = [];
|
|
@@ -540,7 +549,7 @@ function prepareNextInvocation() {
|
|
|
540
549
|
|
|
541
550
|
job.stopTrackingInvocation(cinv);
|
|
542
551
|
|
|
543
|
-
job.invoke();
|
|
552
|
+
job.invoke(cinv.fireDate instanceof CronDate ? cinv.fireDate.toDate() : cinv.fireDate);
|
|
544
553
|
job.emit('run');
|
|
545
554
|
});
|
|
546
555
|
}
|
|
@@ -574,7 +583,7 @@ function scheduleNextRecurrence(rule, job, prevDate, endDate) {
|
|
|
574
583
|
|
|
575
584
|
prevDate = (prevDate instanceof CronDate) ? prevDate : new CronDate();
|
|
576
585
|
|
|
577
|
-
var date = (rule instanceof RecurrenceRule) ? rule.
|
|
586
|
+
var date = (rule instanceof RecurrenceRule) ? rule._nextInvocationDate(prevDate) : rule.next();
|
|
578
587
|
if (date === null) {
|
|
579
588
|
return null;
|
|
580
589
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-schedule",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "A cron-like and not-cron-like job scheduler for Node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"schedule",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"url": "https://github.com/node-schedule/node-schedule.git"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"cron-parser": "^2.
|
|
27
|
+
"cron-parser": "^2.7.3",
|
|
28
28
|
"long-timeout": "0.1.1",
|
|
29
29
|
"sorted-array-functions": "^1.0.0"
|
|
30
30
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var schedule = require('../lib/schedule');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
'Cancel Long Running Job': {
|
|
7
|
+
'should work even when recurring jobs are to be run on the past': function (test) {
|
|
8
|
+
var ok = true;
|
|
9
|
+
var job = schedule.scheduleJob('*/1 * * * * *', function () {
|
|
10
|
+
test.ok(ok);
|
|
11
|
+
var time = Date.now();
|
|
12
|
+
while (ok && (Date.now() - time < 2000)) {
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test.ok(job);
|
|
17
|
+
setTimeout(function () {
|
|
18
|
+
job.cancel();
|
|
19
|
+
test.done();
|
|
20
|
+
ok = false;
|
|
21
|
+
}, 2100);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
package/test/job-test.js
CHANGED
|
@@ -381,6 +381,44 @@ module.exports = {
|
|
|
381
381
|
|
|
382
382
|
clock.tick(2250);
|
|
383
383
|
},
|
|
384
|
+
"Cancelled job reschedules": function(test) {
|
|
385
|
+
test.expect(1);
|
|
386
|
+
var ok = false;
|
|
387
|
+
|
|
388
|
+
var job = schedule.scheduleJob('*/1 * * * * *', function () {});
|
|
389
|
+
|
|
390
|
+
setTimeout(function() {
|
|
391
|
+
job.cancel(true);
|
|
392
|
+
if (job.nextInvocation() !== null) ok = true;
|
|
393
|
+
}, 1250);
|
|
394
|
+
|
|
395
|
+
setTimeout(function() {
|
|
396
|
+
job.cancel();
|
|
397
|
+
test.ok(ok);
|
|
398
|
+
test.done();
|
|
399
|
+
}, 2250);
|
|
400
|
+
|
|
401
|
+
clock.tick(2250);
|
|
402
|
+
},
|
|
403
|
+
"CancelNext job reschedules": function(test) {
|
|
404
|
+
test.expect(1);
|
|
405
|
+
var ok = false;
|
|
406
|
+
|
|
407
|
+
var job = schedule.scheduleJob('*/1 * * * * *', function () {});
|
|
408
|
+
|
|
409
|
+
setTimeout(function() {
|
|
410
|
+
job.cancelNext();
|
|
411
|
+
if (job.nextInvocation() !== null) ok = true;
|
|
412
|
+
}, 1250);
|
|
413
|
+
|
|
414
|
+
setTimeout(function() {
|
|
415
|
+
job.cancel();
|
|
416
|
+
test.ok(ok);
|
|
417
|
+
test.done();
|
|
418
|
+
}, 2250);
|
|
419
|
+
|
|
420
|
+
clock.tick(2250);
|
|
421
|
+
},
|
|
384
422
|
"Job emits 'canceled' event": function(test) {
|
|
385
423
|
test.expect(1);
|
|
386
424
|
|
|
@@ -484,6 +522,29 @@ module.exports = {
|
|
|
484
522
|
test.done();
|
|
485
523
|
}, 2250);
|
|
486
524
|
|
|
525
|
+
clock.tick(2250);
|
|
526
|
+
},
|
|
527
|
+
"Job gets invoked with the fire date": function (test) {
|
|
528
|
+
test.expect(2);
|
|
529
|
+
var prevFireDate;
|
|
530
|
+
var job = new schedule.Job(function (fireDate) {
|
|
531
|
+
if (!prevFireDate) {
|
|
532
|
+
test.ok(fireDate instanceof Date);
|
|
533
|
+
} else {
|
|
534
|
+
test.equal(fireDate.getTime() - prevFireDate.getTime(), 1000);
|
|
535
|
+
}
|
|
536
|
+
prevFireDate = fireDate;
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
job.schedule({
|
|
540
|
+
second: null // fire every second
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
setTimeout(function () {
|
|
544
|
+
job.cancel();
|
|
545
|
+
test.done();
|
|
546
|
+
}, 2250);
|
|
547
|
+
|
|
487
548
|
clock.tick(2250);
|
|
488
549
|
}
|
|
489
550
|
},
|
package/test/start-end-test.js
CHANGED
|
@@ -28,6 +28,7 @@ module.exports = {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
setTimeout(function () {
|
|
31
|
+
job.cancel();
|
|
31
32
|
test.done();
|
|
32
33
|
}, 3250);
|
|
33
34
|
|
|
@@ -49,6 +50,7 @@ module.exports = {
|
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
setTimeout(function () {
|
|
53
|
+
job.cancel();
|
|
52
54
|
test.done();
|
|
53
55
|
}, 3250);
|
|
54
56
|
|
|
@@ -70,6 +72,7 @@ module.exports = {
|
|
|
70
72
|
});
|
|
71
73
|
|
|
72
74
|
setTimeout(function () {
|
|
75
|
+
job.cancel();
|
|
73
76
|
test.done();
|
|
74
77
|
}, 3250);
|
|
75
78
|
|
|
@@ -91,6 +94,7 @@ module.exports = {
|
|
|
91
94
|
});
|
|
92
95
|
|
|
93
96
|
setTimeout(function () {
|
|
97
|
+
job.cancel();
|
|
94
98
|
test.done();
|
|
95
99
|
}, 3250);
|
|
96
100
|
|
|
@@ -113,6 +117,7 @@ module.exports = {
|
|
|
113
117
|
});
|
|
114
118
|
|
|
115
119
|
setTimeout(function () {
|
|
120
|
+
job.cancel();
|
|
116
121
|
test.done();
|
|
117
122
|
}, 3250);
|
|
118
123
|
|
|
@@ -133,6 +138,7 @@ module.exports = {
|
|
|
133
138
|
});
|
|
134
139
|
|
|
135
140
|
setTimeout(function () {
|
|
141
|
+
job.cancel();
|
|
136
142
|
test.done();
|
|
137
143
|
}, 3250);
|
|
138
144
|
|
|
@@ -151,6 +157,7 @@ module.exports = {
|
|
|
151
157
|
});
|
|
152
158
|
|
|
153
159
|
setTimeout(function () {
|
|
160
|
+
job.cancel();
|
|
154
161
|
test.done();
|
|
155
162
|
}, 3250);
|
|
156
163
|
|
|
@@ -169,6 +176,7 @@ module.exports = {
|
|
|
169
176
|
});
|
|
170
177
|
|
|
171
178
|
setTimeout(function () {
|
|
179
|
+
job.cancel();
|
|
172
180
|
test.done();
|
|
173
181
|
}, 3250);
|
|
174
182
|
|
|
@@ -187,6 +195,7 @@ module.exports = {
|
|
|
187
195
|
});
|
|
188
196
|
|
|
189
197
|
setTimeout(function () {
|
|
198
|
+
job.cancel();
|
|
190
199
|
test.done();
|
|
191
200
|
}, 3250);
|
|
192
201
|
|
|
@@ -206,6 +215,7 @@ module.exports = {
|
|
|
206
215
|
});
|
|
207
216
|
|
|
208
217
|
setTimeout(function () {
|
|
218
|
+
job.cancel();
|
|
209
219
|
test.done();
|
|
210
220
|
}, 3250);
|
|
211
221
|
|
|
@@ -226,6 +236,7 @@ module.exports = {
|
|
|
226
236
|
});
|
|
227
237
|
|
|
228
238
|
setTimeout(function () {
|
|
239
|
+
job.cancel();
|
|
229
240
|
test.done();
|
|
230
241
|
}, 3250);
|
|
231
242
|
|
|
@@ -244,6 +255,7 @@ module.exports = {
|
|
|
244
255
|
});
|
|
245
256
|
|
|
246
257
|
setTimeout(function () {
|
|
258
|
+
job.cancel();
|
|
247
259
|
test.done();
|
|
248
260
|
}, 3250);
|
|
249
261
|
|
|
@@ -262,6 +274,7 @@ module.exports = {
|
|
|
262
274
|
});
|
|
263
275
|
|
|
264
276
|
setTimeout(function () {
|
|
277
|
+
job.cancel();
|
|
265
278
|
test.done();
|
|
266
279
|
}, 3250);
|
|
267
280
|
|
|
@@ -280,6 +293,7 @@ module.exports = {
|
|
|
280
293
|
});
|
|
281
294
|
|
|
282
295
|
setTimeout(function () {
|
|
296
|
+
job.cancel();
|
|
283
297
|
test.done();
|
|
284
298
|
}, 3250);
|
|
285
299
|
|
|
@@ -299,6 +313,7 @@ module.exports = {
|
|
|
299
313
|
});
|
|
300
314
|
|
|
301
315
|
setTimeout(function () {
|
|
316
|
+
job.cancel();
|
|
302
317
|
test.done();
|
|
303
318
|
}, 3250);
|
|
304
319
|
|
|
@@ -309,4 +324,4 @@ module.exports = {
|
|
|
309
324
|
clock.restore();
|
|
310
325
|
cb();
|
|
311
326
|
}
|
|
312
|
-
};
|
|
327
|
+
};
|