node-schedule 2.0.0 → 2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Master (Unreleased)
2
2
 
3
+ # 2.1.0 - 28 November, 2021
4
+
5
+ ### New features:
6
+
7
+ - Implement support for graceful shutdown #583
8
+ - Emit a success event after a successful job invocation. #643
9
+
3
10
  # 2.0.0 - 01 February, 2021
4
11
 
5
12
  ### Breaking changes:
package/README.md CHANGED
@@ -57,6 +57,9 @@ or use the convenience function `scheduleJob()` as demonstrated below.
57
57
  Note that `canceled` is the single-L American spelling.
58
58
  * An `error` event when a job invocation triggered by a schedule throws or returns
59
59
  a rejected `Promise`.
60
+ * A `success` event when a job invocation triggered by a schedule returns successfully or
61
+ returns a resolved `Promise`. In any case, the `success` event receives the value returned
62
+ by the callback or in case of a promise, the resolved value.
60
63
 
61
64
  (Both the `scheduled` and `canceled` events receive a JavaScript date object as
62
65
  a parameter).
@@ -230,6 +233,22 @@ const job = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 *
230
233
  });
231
234
  ```
232
235
 
236
+ ### Graceful Shutdown.
237
+ You can shutdown jobs gracefully.
238
+ `gracefulShutdown()` will cancel all jobs and return Promise.
239
+ It will wait until all jobs are terminated.
240
+ ```js
241
+ schedule.gracefulShutdown();
242
+ ```
243
+
244
+ You can also gracefully shutdown jobs when a system interrupt occurs.
245
+ ```
246
+ process.on('SIGINT', function () {
247
+ schedule.gracefulShutdown()
248
+ .then(() => process.exit(0))
249
+ }
250
+ ```
251
+
233
252
  ### Handle Jobs and Job Invocations
234
253
 
235
254
  There are some function to get information for a Job and to handle the Job and
@@ -272,7 +291,7 @@ Before jumping in, check out our [Contributing] page guide!
272
291
 
273
292
  Copyright 2015 Matt Patenaude.
274
293
 
275
- Licensed under the **[MIT License] [license]**.
294
+ Licensed under the **[MIT License](https://github.com/node-schedule/node-schedule/blob/master/LICENSE)**.
276
295
 
277
296
 
278
297
  [cron]: http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5
@@ -280,7 +299,5 @@ Licensed under the **[MIT License] [license]**.
280
299
  [Matt Patenaude]: https://github.com/mattpat
281
300
  [Tejas Manohar]: http://tejas.io
282
301
  [Igor Savin]: https://twitter.com/kibertoad
283
- [license]: https://github.com/node-schedule/node-schedule/blob/master/LICENSE
284
- [Tejas Manohar]: https://github.com/tejasmanohar
285
302
  [our amazing community]: https://github.com/node-schedule/node-schedule/graphs/contributors
286
303
  [cron-parser]: https://github.com/harrisiirak/cron-parser
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const { cancelJob, rescheduleJob, scheduledJobs, scheduleJob} = require('./lib/schedule')
3
+ const { cancelJob, rescheduleJob, scheduledJobs, scheduleJob, gracefulShutdown} = require('./lib/schedule')
4
4
  const { Invocation, RecurrenceRule, Range} = require('./lib/Invocation')
5
5
  const { Job } = require('./lib/Job')
6
6
 
@@ -12,5 +12,6 @@ module.exports = {
12
12
  cancelJob,
13
13
  rescheduleJob,
14
14
  scheduledJobs,
15
- scheduleJob
15
+ scheduleJob,
16
+ gracefulShutdown,
16
17
  }
package/lib/Invocation.js CHANGED
@@ -267,14 +267,23 @@ function prepareNextInvocation() {
267
267
  try {
268
268
  const result = job.invoke(cinv.fireDate instanceof CronDate ? cinv.fireDate.toDate() : cinv.fireDate);
269
269
  job.emit('run');
270
+ job.running += 1;
270
271
 
271
272
  if (result instanceof Promise) {
272
- result.catch(function (err) {
273
+ result.then(function (value) {
274
+ job.emit('success', value);
275
+ job.running -= 1;
276
+ }).catch(function (err) {
273
277
  job.emit('error', err);
278
+ job.running -= 1;
274
279
  });
280
+ } else {
281
+ job.emit('success', result);
282
+ job.running -= 1;
275
283
  }
276
284
  } catch (err) {
277
285
  job.emit('error', err);
286
+ job.running -= 1;
278
287
  }
279
288
 
280
289
  if (job.isOneTimeJob) {
package/lib/Job.js CHANGED
@@ -41,6 +41,9 @@ function Job(name, job, callback) {
41
41
  this.callback = typeof callback === 'function' ? callback : false;
42
42
  }
43
43
 
44
+ // task count
45
+ this.running = 0;
46
+
44
47
  // Check for generator
45
48
  if (typeof this.job === 'function' &&
46
49
  this.job.prototype &&
package/lib/schedule.js CHANGED
@@ -49,7 +49,7 @@ function rescheduleJob(job, spec) {
49
49
  return job;
50
50
  }
51
51
  } else if (typeof job === 'string') {
52
- if (scheduledJobs.hasOwnProperty(job)) {
52
+ if (Object.prototype.hasOwnProperty.call(scheduledJobs, job)) {
53
53
  if (scheduledJobs[job].reschedule(spec)) {
54
54
  return scheduledJobs[job];
55
55
  }
@@ -65,7 +65,7 @@ function cancelJob(job) {
65
65
  if (job instanceof Job) {
66
66
  success = job.cancel();
67
67
  } else if (typeof job == 'string' || job instanceof String) {
68
- if (job in scheduledJobs && scheduledJobs.hasOwnProperty(job)) {
68
+ if (job in scheduledJobs && Object.prototype.hasOwnProperty.call(scheduledJobs, job)) {
69
69
  success = scheduledJobs[job].cancel();
70
70
  }
71
71
  }
@@ -73,10 +73,42 @@ function cancelJob(job) {
73
73
  return success;
74
74
  }
75
75
 
76
+ function gracefulShutdown() {
77
+ const jobs = Object.keys(scheduledJobs).map(key => scheduledJobs[key]);
78
+ jobs.forEach(function (job) {
79
+ job.cancel();
80
+ });
81
+
82
+ let running = false;
83
+ for (let i = 0; i < jobs.length; i++) {
84
+ if (jobs[i].running > 0) {
85
+ running = true;
86
+ break;
87
+ }
88
+ }
89
+
90
+ return new Promise(function (resolve) {
91
+ if (running) {
92
+ setInterval(function () {
93
+ for (let i = 0; i < jobs.length; i++) {
94
+ if (jobs[i].running > 0) {
95
+ return;
96
+ }
97
+ }
98
+
99
+ resolve();
100
+ }, 500);
101
+ } else {
102
+ resolve();
103
+ }
104
+ });
105
+ }
106
+
76
107
  /* Public API */
77
108
  module.exports = {
78
109
  scheduleJob,
79
110
  rescheduleJob,
80
111
  scheduledJobs,
81
- cancelJob
112
+ cancelJob,
113
+ gracefulShutdown,
82
114
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-schedule",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "A cron-like and not-cron-like job scheduler for Node.",
5
5
  "keywords": [
6
6
  "schedule",
@@ -36,16 +36,16 @@
36
36
  "url": "https://github.com/node-schedule/node-schedule.git"
37
37
  },
38
38
  "dependencies": {
39
- "cron-parser": "^3.1.0",
39
+ "cron-parser": "^3.5.0",
40
40
  "long-timeout": "0.1.1",
41
41
  "sorted-array-functions": "^1.3.0"
42
42
  },
43
43
  "devDependencies": {
44
- "airtap": "^4.0.1",
45
- "eslint": "^7.18.0",
44
+ "airtap": "^4.0.4",
45
+ "eslint": "^8.3.0",
46
46
  "nyc": "^15.1.0",
47
47
  "sinon": "^9.2.4",
48
- "tape": "^5.1.1"
48
+ "tape": "^5.3.2"
49
49
  },
50
50
  "engines": {
51
51
  "node": ">=6"