Skip to content

Commit

Permalink
Graceful shutdown (#583)
Browse files Browse the repository at this point in the history
  • Loading branch information
changmyeong committed Nov 28, 2021
1 parent 3f88a9a commit 267951b
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 8 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,22 @@ const job = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 *
});
```

### Graceful Shutdown.
You can shutdown jobs gracefully.
`gracefulShutdown()` will cancel all jobs and return Promise.
It will wait until all jobs are terminated.
```js
schedule.gracefulShutdown();
```

You can also gracefully shutdown jobs when a system interrupt occurs.
```
process.on('SIGINT', function () {
schedule.gracefulShutdown()
.then(() => process.exit(0))
}
```

### Handle Jobs and Job Invocations

There are some function to get information for a Job and to handle the Job and
Expand Down
5 changes: 3 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const { cancelJob, rescheduleJob, scheduledJobs, scheduleJob} = require('./lib/schedule')
const { cancelJob, rescheduleJob, scheduledJobs, scheduleJob, gracefulShutdown} = require('./lib/schedule')
const { Invocation, RecurrenceRule, Range} = require('./lib/Invocation')
const { Job } = require('./lib/Job')

Expand All @@ -12,5 +12,6 @@ module.exports = {
cancelJob,
rescheduleJob,
scheduledJobs,
scheduleJob
scheduleJob,
gracefulShutdown,
}
14 changes: 9 additions & 5 deletions lib/Invocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,19 +267,23 @@ function prepareNextInvocation() {
try {
const result = job.invoke(cinv.fireDate instanceof CronDate ? cinv.fireDate.toDate() : cinv.fireDate);
job.emit('run');
job.running += 1;

if (result instanceof Promise) {
result.then(function(value) {
result.then(function (value) {
job.emit('success', value);
})
.catch(function (err) {
job.emit('error', err);
});
job.running -= 1;
}).catch(function (err) {
job.emit('error', err);
job.running -= 1;
});
} else {
job.emit('success', result);
job.running -= 1;
}
} catch (err) {
job.emit('error', err);
job.running -= 1;
}

if (job.isOneTimeJob) {
Expand Down
3 changes: 3 additions & 0 deletions lib/Job.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ function Job(name, job, callback) {
this.callback = typeof callback === 'function' ? callback : false;
}

// task count
this.running = 0;

// Check for generator
if (typeof this.job === 'function' &&
this.job.prototype &&
Expand Down
34 changes: 33 additions & 1 deletion lib/schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,42 @@ function cancelJob(job) {
return success;
}

function gracefulShutdown() {
const jobs = Object.keys(scheduledJobs).map(key => scheduledJobs[key]);
jobs.forEach(function (job) {
job.cancel();
});

let running = false;
for (let i = 0; i < jobs.length; i++) {
if (jobs[i].running > 0) {
running = true;
break;
}
}

return new Promise(function (resolve) {
if (running) {
setInterval(function () {
for (let i = 0; i < jobs.length; i++) {
if (jobs[i].running > 0) {
return;
}
}

resolve();
}, 500);
} else {
resolve();
}
});
}

/* Public API */
module.exports = {
scheduleJob,
rescheduleJob,
scheduledJobs,
cancelJob
cancelJob,
gracefulShutdown,
}
23 changes: 23 additions & 0 deletions test/graceful-shutdown-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

const test = require('tape');
const schedule = require('..');

test('Graceful Shutdown', function (t) {
t.test('pending when job running', function (test) {
test.plan(1);
const job = schedule.scheduleJob('* * * * * *', function () {
});

job.running = 1;
schedule.gracefulShutdown().then(function() {
test.ok(true);
});

job.running = 0;
schedule.gracefulShutdown().then(function() {
test.ok(true);
test.end();
});
});
});

0 comments on commit 267951b

Please sign in to comment.