node-schedule 1.0.0 → 1.1.0

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/.npmignore CHANGED
@@ -1,6 +1,2 @@
1
- coverage
2
- node_modules
3
- node-schedule.tmproj
4
- .DS_Store
5
- npm-debug.log
6
-
1
+ *.sublime*
2
+ .npmrc
package/README.md CHANGED
@@ -164,10 +164,10 @@ var j = schedule.scheduleJob(rule, function(){
164
164
  });
165
165
  ```
166
166
 
167
- It's worth noting that the default value of a component of a recurrence rule is
168
- `null` (except for seconds, which is 0 for familiarity with cron). If we did not
167
+ > **Note**: It's worth noting that the default value of a component of a recurrence rule is
168
+ `null` (except for seconds, which is 0 for familiarity with cron). *If we did not
169
169
  explicitly set `minute` to 0 above, the message would have instead been logged at
170
- 5:00pm, 5:01pm, 5:02pm, ..., 5:59pm. Probably not what you want.
170
+ 5:00pm, 5:01pm, 5:02pm, ..., 5:59pm.* Probably not what you want.
171
171
 
172
172
  #### Object Literal Syntax
173
173
 
package/lib/schedule.js CHANGED
@@ -25,6 +25,9 @@ function Job(name, job, callback) {
25
25
  // setup a private pendingInvocations variable
26
26
  var pendingInvocations = [];
27
27
 
28
+ //setup a private number of invocations variable
29
+ var triggeredJobs = 0;
30
+
28
31
  // Set scope vars
29
32
  var jobName = name && typeof name === 'string' ? name : '<Anonymous Job ' + (++anonJobCounter) + '>';
30
33
  this.job = name && typeof name === 'function' ? name : job;
@@ -73,6 +76,12 @@ function Job(name, job, callback) {
73
76
 
74
77
  return false;
75
78
  };
79
+ this.triggeredJobs = function() {
80
+ return triggeredJobs;
81
+ };
82
+ this.setTriggeredJobs = function(triggeredJob) {
83
+ triggeredJobs = triggeredJob;
84
+ };
76
85
  this.cancel = function(reschedule) {
77
86
  reschedule = (typeof reschedule == 'boolean') ? reschedule : false;
78
87
 
@@ -100,7 +109,7 @@ function Job(name, job, callback) {
100
109
  // remove from scheduledJobs if reschedule === false
101
110
  if (!reschedule) {
102
111
  if (this.name) {
103
- scheduledJobs[this.name] = null;
112
+ delete scheduledJobs[this.name];
104
113
  }
105
114
  }
106
115
 
@@ -127,6 +136,26 @@ function Job(name, job, callback) {
127
136
 
128
137
  return true;
129
138
  };
139
+ this.reschedule = function(spec) {
140
+ var inv;
141
+ var cInvs = pendingInvocations.slice();
142
+
143
+ for (var j = 0; j < cInvs.length; j++) {
144
+ inv = cInvs[j];
145
+
146
+ cancelInvocation(inv);
147
+ }
148
+
149
+ pendingInvocations = [];
150
+
151
+ if (this.schedule(spec)) {
152
+ this.setTriggeredJobs(0);
153
+ return true;
154
+ } else {
155
+ pendingInvocations = cInvs;
156
+ return false;
157
+ }
158
+ };
130
159
  this.nextInvocation = function() {
131
160
  if (!pendingInvocations.length) {
132
161
  return null;
@@ -142,6 +171,7 @@ util.inherits(Job, events.EventEmitter);
142
171
 
143
172
  Job.prototype.invoke = function() {
144
173
  if (typeof this.job == 'function') {
174
+ this.setTriggeredJobs(this.triggeredJobs() + 1);
145
175
  this.job();
146
176
  } else {
147
177
  this.job.execute();
@@ -367,7 +397,7 @@ function runOnDate(date, job) {
367
397
  var then = date.getTime();
368
398
 
369
399
  if (then < now) {
370
- process.nextTick(job);
400
+ setImmediate(job);
371
401
  return null;
372
402
  }
373
403
 
@@ -478,6 +508,21 @@ function scheduleJob() {
478
508
  return null;
479
509
  }
480
510
 
511
+ function rescheduleJob(job, spec) {
512
+ if (job instanceof Job) {
513
+ if (job.reschedule(spec)) {
514
+ return job;
515
+ }
516
+ } else if (typeof job == 'string' || job instanceof String) {
517
+ if (job in scheduledJobs && scheduledJobs.hasOwnProperty(job)) {
518
+ if (scheduledJobs[job].reschedule(spec)) {
519
+ return scheduledJobs[job];
520
+ }
521
+ }
522
+ }
523
+ return null;
524
+ }
525
+
481
526
  function cancelJob(job) {
482
527
  var success = false;
483
528
  if (job instanceof Job) {
@@ -497,5 +542,6 @@ module.exports.Range = Range;
497
542
  module.exports.RecurrenceRule = RecurrenceRule;
498
543
  module.exports.Invocation = Invocation;
499
544
  module.exports.scheduleJob = scheduleJob;
545
+ module.exports.rescheduleJob = rescheduleJob;
500
546
  module.exports.scheduledJobs = scheduledJobs;
501
547
  module.exports.cancelJob = cancelJob;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-schedule",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A cron-like and not-cron-like job scheduler for Node.",
5
5
  "keywords": [
6
6
  "schedule",
@@ -199,6 +199,362 @@ module.exports = {
199
199
  clock.tick(3250);
200
200
  }
201
201
  },
202
+ ".rescheduleJob(job, {...})": {
203
+ "Reschedule jobs from object based to object based": function(test) {
204
+ test.expect(3);
205
+
206
+ var job = new schedule.scheduleJob({
207
+ second: null
208
+ }, function() {
209
+ test.ok(true);
210
+ });
211
+
212
+ setTimeout(function() {
213
+ schedule.rescheduleJob(job, {
214
+ minute: null
215
+ });
216
+ }, 3250);
217
+
218
+ setTimeout(function() {
219
+ job.cancel();
220
+ test.done();
221
+ }, 5000);
222
+
223
+ clock.tick(5000);
224
+ },
225
+ "Reschedule jobs from every minutes to every second": function(test) {
226
+ test.expect(3);
227
+
228
+ var timeout = 60 * 1000;
229
+
230
+ var job = new schedule.scheduleJob({
231
+ minute: null
232
+ }, function() {
233
+ test.ok(true);
234
+ });
235
+
236
+ setTimeout(function() {
237
+ schedule.rescheduleJob(job, {
238
+ second: null
239
+ });
240
+ }, timeout);
241
+
242
+ setTimeout(function() {
243
+ job.cancel();
244
+ test.done();
245
+ }, timeout + 2250);
246
+
247
+ clock.tick(timeout + 2250);
248
+ }
249
+ },
250
+ ".rescheduleJob(job, Date)": {
251
+ "Reschedule jobs from Date to Date": function(test) {
252
+ test.expect(1);
253
+
254
+ var job = new schedule.scheduleJob(new Date(Date.now() + 3000), function() {
255
+ test.ok(true);
256
+ });
257
+
258
+ setTimeout(function() {
259
+ schedule.rescheduleJob(job, new Date(Date.now() + 5000));
260
+ }, 1000);
261
+
262
+ setTimeout(function() {
263
+ test.done();
264
+ }, 6150);
265
+
266
+ clock.tick(6150);
267
+ },
268
+ "Reschedule jobs that has been executed": function(test) {
269
+ test.expect(2);
270
+
271
+ var job = new schedule.scheduleJob(new Date(Date.now() + 1000), function() {
272
+ test.ok(true);
273
+ });
274
+
275
+ setTimeout(function() {
276
+ schedule.rescheduleJob(job, new Date(Date.now() + 2000));
277
+ }, 2000);
278
+
279
+ setTimeout(function() {
280
+ test.done();
281
+ }, 5150);
282
+
283
+ clock.tick(5150);
284
+ }
285
+ },
286
+ ".rescheduleJob(job, RecurrenceRule)": {
287
+ "Reschedule jobs from RecurrenceRule to RecurrenceRule": function(test) {
288
+ test.expect(3);
289
+
290
+ var timeout = 60 * 1000;
291
+
292
+ var rule = new schedule.RecurrenceRule();
293
+ rule.second = null; // fire every second
294
+
295
+ var job = schedule.scheduleJob(rule, function() {
296
+ test.ok(true);
297
+ });
298
+
299
+ var newRule = new schedule.RecurrenceRule();
300
+ newRule.minute = null;
301
+
302
+ setTimeout(function() {
303
+ schedule.rescheduleJob(job, newRule);
304
+ }, 2250);
305
+
306
+ setTimeout(function() {
307
+ job.cancel();
308
+ test.done();
309
+ }, timeout + 2250);
310
+
311
+ clock.tick(timeout + 2250);
312
+ },
313
+ "Reschedule jobs from RecurrenceRule to Date": function(test) {
314
+ test.expect(3);
315
+
316
+ var rule = new schedule.RecurrenceRule();
317
+ rule.second = null; // fire every second
318
+
319
+ var job = schedule.scheduleJob(rule, function() {
320
+ test.ok(true);
321
+ });
322
+
323
+ setTimeout(function() {
324
+ schedule.rescheduleJob(job, new Date(Date.now() + 2000));
325
+ }, 2150);
326
+
327
+ setTimeout(function() {
328
+ test.done();
329
+ }, 4250);
330
+
331
+ clock.tick(4250);
332
+ },
333
+ "Reschedule jobs from RecurrenceRule to {...}": function(test) {
334
+ test.expect(3);
335
+
336
+ var timeout = 60 * 1000;
337
+
338
+ var rule = new schedule.RecurrenceRule();
339
+ rule.second = null; // fire every second
340
+
341
+ var job = schedule.scheduleJob(rule, function() {
342
+ test.ok(true);
343
+ });
344
+
345
+ setTimeout(function() {
346
+ schedule.rescheduleJob(job, {
347
+ minute: null
348
+ });
349
+ }, 2150);
350
+
351
+ setTimeout(function() {
352
+ job.cancel();
353
+ test.done();
354
+ }, timeout + 2150);
355
+
356
+ clock.tick(timeout + 2150);
357
+ },
358
+ "Reschedule jobs that is not available": function(test) {
359
+ test.expect(4);
360
+
361
+ var rule = new schedule.RecurrenceRule();
362
+ rule.second = null; // fire every second
363
+
364
+ var job = schedule.scheduleJob(rule, function() {
365
+ test.ok(true);
366
+ });
367
+
368
+ setTimeout(function() {
369
+ schedule.rescheduleJob(null, new Date(Date.now() + 2000));
370
+ }, 2150);
371
+
372
+ setTimeout(function() {
373
+ job.cancel();
374
+ test.done();
375
+ }, 4250);
376
+
377
+ clock.tick(4250);
378
+ }
379
+ },
380
+ '.rescheduleJob("job name", {...})': {
381
+ "Reschedule jobs from object based to object based": function(test) {
382
+ test.expect(3);
383
+
384
+ var job = new schedule.scheduleJob({
385
+ second: null
386
+ }, function() {
387
+ test.ok(true);
388
+ });
389
+
390
+ setTimeout(function() {
391
+ schedule.rescheduleJob(job.name, {
392
+ minute: null
393
+ });
394
+ }, 3250);
395
+
396
+ setTimeout(function() {
397
+ job.cancel();
398
+ test.done();
399
+ }, 5000);
400
+
401
+ clock.tick(5000);
402
+ },
403
+ "Reschedule jobs from every minutes to every second": function(test) {
404
+ test.expect(3);
405
+
406
+ var timeout = 60 * 1000;
407
+
408
+ var job = new schedule.scheduleJob({
409
+ minute: null
410
+ }, function() {
411
+ test.ok(true);
412
+ });
413
+
414
+ setTimeout(function() {
415
+ schedule.rescheduleJob(job.name, {
416
+ second: null
417
+ });
418
+ }, timeout);
419
+
420
+ setTimeout(function() {
421
+ job.cancel();
422
+ test.done();
423
+ }, timeout + 2250);
424
+
425
+ clock.tick(timeout + 2250);
426
+ }
427
+ },
428
+ '.rescheduleJob("job name", Date)': {
429
+ "Reschedule jobs from Date to Date": function(test) {
430
+ test.expect(1);
431
+
432
+ var job = new schedule.scheduleJob(new Date(Date.now() + 3000), function() {
433
+ test.ok(true);
434
+ });
435
+
436
+ setTimeout(function() {
437
+ schedule.rescheduleJob(job.name, new Date(Date.now() + 5000));
438
+ }, 1000);
439
+
440
+ setTimeout(function() {
441
+ test.done();
442
+ }, 6150);
443
+
444
+ clock.tick(6150);
445
+ },
446
+ "Reschedule jobs that has been executed": function(test) {
447
+ test.expect(2);
448
+
449
+ var job = new schedule.scheduleJob(new Date(Date.now() + 1000), function() {
450
+ test.ok(true);
451
+ });
452
+
453
+ setTimeout(function() {
454
+ schedule.rescheduleJob(job.name, new Date(Date.now() + 2000));
455
+ }, 2000);
456
+
457
+ setTimeout(function() {
458
+ test.done();
459
+ }, 5150);
460
+
461
+ clock.tick(5150);
462
+ }
463
+ },
464
+ '.rescheduleJob("job name", RecurrenceRule)': {
465
+ "Reschedule jobs from RecurrenceRule to RecurrenceRule": function(test) {
466
+ test.expect(3);
467
+
468
+ var timeout = 60 * 1000;
469
+
470
+ var rule = new schedule.RecurrenceRule();
471
+ rule.second = null; // fire every second
472
+
473
+ var job = schedule.scheduleJob(rule, function() {
474
+ test.ok(true);
475
+ });
476
+
477
+ var newRule = new schedule.RecurrenceRule();
478
+ newRule.minute = null;
479
+
480
+ setTimeout(function() {
481
+ schedule.rescheduleJob(job.name, newRule);
482
+ }, 2250);
483
+
484
+ setTimeout(function() {
485
+ job.cancel();
486
+ test.done();
487
+ }, timeout + 2250);
488
+
489
+ clock.tick(timeout + 2250);
490
+ },
491
+ "Reschedule jobs from RecurrenceRule to Date": function(test) {
492
+ test.expect(3);
493
+
494
+ var rule = new schedule.RecurrenceRule();
495
+ rule.second = null; // fire every second
496
+
497
+ var job = schedule.scheduleJob(rule, function() {
498
+ test.ok(true);
499
+ });
500
+
501
+ setTimeout(function() {
502
+ schedule.rescheduleJob(job.name, new Date(Date.now() + 2000));
503
+ }, 2150);
504
+
505
+ setTimeout(function() {
506
+ test.done();
507
+ }, 4250);
508
+
509
+ clock.tick(4250);
510
+ },
511
+ "Reschedule jobs from RecurrenceRule to {...}": function(test) {
512
+ test.expect(3);
513
+
514
+ var timeout = 60 * 1000;
515
+
516
+ var rule = new schedule.RecurrenceRule();
517
+ rule.second = null; // fire every second
518
+
519
+ var job = schedule.scheduleJob(rule, function() {
520
+ test.ok(true);
521
+ });
522
+
523
+ setTimeout(function() {
524
+ schedule.rescheduleJob(job.name, {
525
+ minute: null
526
+ });
527
+ }, 2150);
528
+
529
+ setTimeout(function() {
530
+ job.cancel();
531
+ test.done();
532
+ }, timeout + 2150);
533
+
534
+ clock.tick(timeout + 2150);
535
+ },
536
+ "Reschedule jobs that is not available": function(test) {
537
+ test.expect(4);
538
+
539
+ var rule = new schedule.RecurrenceRule();
540
+ rule.second = null; // fire every second
541
+
542
+ var job = schedule.scheduleJob(rule, function() {
543
+ test.ok(true);
544
+ });
545
+
546
+ setTimeout(function() {
547
+ schedule.rescheduleJob("Blah", new Date(Date.now() + 2000));
548
+ }, 2150);
549
+
550
+ setTimeout(function() {
551
+ job.cancel();
552
+ test.done();
553
+ }, 4250);
554
+
555
+ clock.tick(4250);
556
+ }
557
+ },
202
558
  ".cancelJob(Job)": {
203
559
  "Prevents all future invocations of Job passed in": function(test) {
204
560
  test.expect(2);
package/test/job-test.js CHANGED
@@ -417,19 +417,42 @@ module.exports = {
417
417
  function() {},
418
418
  function() {});
419
419
 
420
- test.equal(schedule.scheduledJobs.cancelJob, job1);
421
- test.equal(schedule.scheduledJobs.second, job2);
420
+ test.strictEqual(schedule.scheduledJobs.cancelJob, job1);
421
+ test.strictEqual(schedule.scheduledJobs.second, job2);
422
422
  setTimeout(function() {
423
423
  job1.cancel();
424
424
  job2.cancel();
425
- test.equal(schedule.scheduledJobs.cancelJob, null);
426
- test.equal(schedule.scheduledJobs.second, null);
425
+ test.strictEqual(schedule.scheduledJobs.cancelJob, undefined);
426
+ test.strictEqual(schedule.scheduledJobs.second, undefined);
427
427
  test.done();
428
428
  }, 1250);
429
429
 
430
430
  clock.tick(1250);
431
431
  }
432
432
  },
433
+ "#reschedule": {
434
+ "When rescheduled counter will be reset to zero": function(test) {
435
+
436
+ var job = new schedule.scheduleJob({
437
+ second: null
438
+ }, function() {});
439
+
440
+ setTimeout(function() {
441
+ test.equal(job.triggeredJobs(), 3);
442
+ schedule.rescheduleJob(job, {
443
+ minute: null
444
+ });
445
+ }, 3250);
446
+
447
+ setTimeout(function() {
448
+ job.cancel();
449
+ test.equal(job.triggeredJobs(), 0);
450
+ test.done();
451
+ }, 5000);
452
+
453
+ clock.tick(5000);
454
+ }
455
+ },
433
456
  "When invoked": {
434
457
  "Job emits 'run' event": function(test) {
435
458
  test.expect(1);
@@ -447,6 +470,21 @@ module.exports = {
447
470
  }, 3250);
448
471
 
449
472
  clock.tick(3250);
473
+ },
474
+ "Job counter increase properly": function(test) {
475
+ var job = new schedule.Job(function() {});
476
+
477
+ job.schedule({
478
+ second: null // fire every second
479
+ });
480
+
481
+ setTimeout(function() {
482
+ job.cancel();
483
+ test.equal(job.triggeredJobs(), 2);
484
+ test.done();
485
+ }, 2250);
486
+
487
+ clock.tick(2250);
450
488
  }
451
489
  },
452
490
  tearDown: function(cb) {