fix: graceful shutdown (#3821)

* fix: missing graceful shutdown handler

* fix: asar - use async fs operation

* fix: scheduler - graceful shutdown and wait for running jobs to complete
This commit is contained in:
LK HO 2021-04-12 23:45:33 +08:00 committed by GitHub
parent 71aa0c9346
commit a103127545
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 23 deletions

View File

@ -40,11 +40,11 @@ module.exports = {
} }
}, },
async unload () { async unload () {
if (this.fdCache) { const fds = Object.values(this.fdCache)
if (fds.length > 0) {
WIKI.logger.info('Closing ASAR file descriptors...') WIKI.logger.info('Closing ASAR file descriptors...')
for (const fdItem in this.fdCache) { const closeAsync = require('util').promisify(fs.close)
fs.closeSync(this.fdCache[fdItem].fd) await Promise.all(fds.map(x => closeAsync(x.fd)))
}
this.fdCache = {} this.fdCache = {}
} }
}, },

View File

@ -107,19 +107,21 @@ module.exports = {
* Graceful shutdown * Graceful shutdown
*/ */
async shutdown () { async shutdown () {
if (WIKI.models) { if (WIKI.servers) {
await WIKI.models.unsubscribeToNotifications() await WIKI.servers.stopServers()
await WIKI.models.knex.client.pool.destroy()
await WIKI.models.knex.destroy()
} }
if (WIKI.scheduler) { if (WIKI.scheduler) {
WIKI.scheduler.stop() await WIKI.scheduler.stop()
}
if (WIKI.models) {
await WIKI.models.unsubscribeToNotifications()
if (WIKI.models.knex) {
await WIKI.models.knex.destroy()
}
} }
if (WIKI.asar) { if (WIKI.asar) {
await WIKI.asar.unload() await WIKI.asar.unload()
} }
if (WIKI.servers) { process.exit(0)
await WIKI.servers.stopServers()
}
} }
} }

View File

@ -12,7 +12,8 @@ class Job {
schedule = 'P1D', schedule = 'P1D',
repeat = false, repeat = false,
worker = false worker = false
}) { }, queue) {
this.queue = queue
this.finished = Promise.resolve() this.finished = Promise.resolve()
this.name = name this.name = name
this.immediate = immediate this.immediate = immediate
@ -27,6 +28,7 @@ class Job {
* @param {Object} data Job Data * @param {Object} data Job Data
*/ */
start(data) { start(data) {
this.queue.jobs.push(this)
if (this.immediate) { if (this.immediate) {
this.invoke(data) this.invoke(data)
} else { } else {
@ -82,16 +84,20 @@ class Job {
} catch (err) { } catch (err) {
WIKI.logger.warn(err) WIKI.logger.warn(err)
} }
if (this.repeat) { if (this.repeat && this.queue.jobs.includes(this)) {
this.queue(data) this.queue(data)
} else {
this.stop().catch(() => {})
} }
} }
/** /**
* Stop any future job invocation from occuring * Stop any future job invocation from occuring
*/ */
stop() { async stop() {
clearTimeout(this.timeout) clearTimeout(this.timeout)
this.queue.jobs = this.queue.jobs.filter(x => x !== this)
return this.finished
} }
} }
@ -118,16 +124,11 @@ module.exports = {
}) })
}, },
registerJob(opts, data) { registerJob(opts, data) {
const job = new Job(opts) const job = new Job(opts, this)
job.start(data) job.start(data)
if (job.repeat) {
this.jobs.push(job)
}
return job return job
}, },
stop() { async stop() {
this.jobs.forEach(job => { return Promise.all(this.jobs.map(job => job.stop()))
job.stop()
})
} }
} }

View File

@ -33,3 +33,16 @@ WIKI.logger = require('./core/logger').init('MASTER')
// ---------------------------------------- // ----------------------------------------
WIKI.kernel.init() WIKI.kernel.init()
// ----------------------------------------
// Register exit handler
// ----------------------------------------
process.on('SIGINT', () => {
WIKI.kernel.shutdown()
})
process.on('message', (msg) => {
if (msg === 'shutdown') {
WIKI.kernel.shutdown()
}
})