node-schedule 2.0.0 → 2.1.1

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,18 @@
1
1
  # Master (Unreleased)
2
2
 
3
+ # 2.1.1 - 11 January, 2023
4
+
5
+ ### Bug fixes:
6
+
7
+ - Bump cron-parser from 3.5.0 to 4.2.0 - security fix #642
8
+
9
+ # 2.1.0 - 28 November, 2021
10
+
11
+ ### New features:
12
+
13
+ - Implement support for graceful shutdown #583
14
+ - Emit a success event after a successful job invocation. #643
15
+
3
16
  # 2.0.0 - 01 February, 2021
4
17
 
5
18
  ### 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).
@@ -180,6 +183,7 @@ Timezones are also supported. Here is an example of executing at the start of ev
180
183
  ```js
181
184
  const rule = new schedule.RecurrenceRule();
182
185
  rule.hour = 0;
186
+ rule.minute = 0;
183
187
  rule.tz = 'Etc/UTC';
184
188
 
185
189
  const job = schedule.scheduleJob(rule, function(){
@@ -230,6 +234,22 @@ const job = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 *
230
234
  });
231
235
  ```
232
236
 
237
+ ### Graceful Shutdown.
238
+ You can shutdown jobs gracefully.
239
+ `gracefulShutdown()` will cancel all jobs and return Promise.
240
+ It will wait until all jobs are terminated.
241
+ ```js
242
+ schedule.gracefulShutdown();
243
+ ```
244
+
245
+ You can also gracefully shutdown jobs when a system interrupt occurs.
246
+ ```
247
+ process.on('SIGINT', function () {
248
+ schedule.gracefulShutdown()
249
+ .then(() => process.exit(0))
250
+ }
251
+ ```
252
+
233
253
  ### Handle Jobs and Job Invocations
234
254
 
235
255
  There are some function to get information for a Job and to handle the Job and
@@ -272,7 +292,7 @@ Before jumping in, check out our [Contributing] page guide!
272
292
 
273
293
  Copyright 2015 Matt Patenaude.
274
294
 
275
- Licensed under the **[MIT License] [license]**.
295
+ Licensed under the **[MIT License](https://github.com/node-schedule/node-schedule/blob/master/LICENSE)**.
276
296
 
277
297
 
278
298
  [cron]: http://unixhelp.ed.ac.uk/CGI/man-cgi?crontab+5
@@ -280,7 +300,5 @@ Licensed under the **[MIT License] [license]**.
280
300
  [Matt Patenaude]: https://github.com/mattpat
281
301
  [Tejas Manohar]: http://tejas.io
282
302
  [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
303
  [our amazing community]: https://github.com/node-schedule/node-schedule/graphs/contributors
286
304
  [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.1",
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": "^4.2.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"