schedule.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. 'use strict';
  2. /*
  3. node-schedule
  4. A cron-like and not-cron-like job scheduler for Node.
  5. */
  6. const { Job, scheduledJobs } = require('./Job')
  7. /* API
  8. invoke()
  9. runOnDate(date)
  10. schedule(date || recurrenceRule || cronstring)
  11. cancel(reschedule = false)
  12. cancelNext(reschedule = true)
  13. Property constraints
  14. name: readonly
  15. job: readwrite
  16. */
  17. /* Convenience methods */
  18. function scheduleJob() {
  19. if (arguments.length < 2) {
  20. throw new RangeError('Invalid number of arguments');
  21. }
  22. const name = (arguments.length >= 3 && typeof arguments[0] === 'string') ? arguments[0] : null;
  23. const spec = name ? arguments[1] : arguments[0];
  24. const method = name ? arguments[2] : arguments[1];
  25. const callback = name ? arguments[3] : arguments[2];
  26. if (typeof method !== 'function') {
  27. throw new RangeError('The job method must be a function.');
  28. }
  29. const job = new Job(name, method, callback);
  30. if (job.schedule(spec)) {
  31. return job;
  32. }
  33. return null;
  34. }
  35. function rescheduleJob(job, spec) {
  36. if (job instanceof Job) {
  37. if (job.reschedule(spec)) {
  38. return job;
  39. }
  40. } else if (typeof job === 'string') {
  41. if (Object.prototype.hasOwnProperty.call(scheduledJobs, job)) {
  42. if (scheduledJobs[job].reschedule(spec)) {
  43. return scheduledJobs[job];
  44. }
  45. } else {
  46. throw new Error('Cannot reschedule one-off job by name, pass job reference instead')
  47. }
  48. }
  49. return null;
  50. }
  51. function cancelJob(job) {
  52. let success = false;
  53. if (job instanceof Job) {
  54. success = job.cancel();
  55. } else if (typeof job == 'string' || job instanceof String) {
  56. if (job in scheduledJobs && Object.prototype.hasOwnProperty.call(scheduledJobs, job)) {
  57. success = scheduledJobs[job].cancel();
  58. }
  59. }
  60. return success;
  61. }
  62. function gracefulShutdown() {
  63. const jobs = Object.keys(scheduledJobs).map(key => scheduledJobs[key]);
  64. jobs.forEach(function (job) {
  65. job.cancel();
  66. });
  67. let running = false;
  68. for (let i = 0; i < jobs.length; i++) {
  69. if (jobs[i].running > 0) {
  70. running = true;
  71. break;
  72. }
  73. }
  74. return new Promise(function (resolve) {
  75. if (running) {
  76. setInterval(function () {
  77. for (let i = 0; i < jobs.length; i++) {
  78. if (jobs[i].running > 0) {
  79. return;
  80. }
  81. }
  82. resolve();
  83. }, 500);
  84. } else {
  85. resolve();
  86. }
  87. });
  88. }
  89. /* Public API */
  90. module.exports = {
  91. scheduleJob,
  92. rescheduleJob,
  93. scheduledJobs,
  94. cancelJob,
  95. gracefulShutdown,
  96. }