mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Improved ghost-server with async/await
- Using consistent patterns for shutdown and stop - Make it clear what each method does - Use async/await to make the code more readable and simple - This lays groundwork for having more cleanup tasks in stop than just server.stop()
This commit is contained in:
parent
1f69b22b30
commit
624206b6d7
1 changed files with 49 additions and 40 deletions
|
@ -14,7 +14,6 @@ const logging = require('../shared/logging');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
||||||
const stoppable = require('stoppable');
|
const stoppable = require('stoppable');
|
||||||
const {reject} = require('bluebird');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## GhostServer
|
* ## GhostServer
|
||||||
|
@ -103,7 +102,7 @@ class GhostServer {
|
||||||
|
|
||||||
self.httpServer.on('listening', function () {
|
self.httpServer.on('listening', function () {
|
||||||
debug('...Started');
|
debug('...Started');
|
||||||
self.logStartMessages();
|
self._logStartMessages();
|
||||||
|
|
||||||
return GhostServer.announceServerReadiness()
|
return GhostServer.announceServerReadiness()
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -113,21 +112,10 @@ class GhostServer {
|
||||||
|
|
||||||
stoppable(self.httpServer, config.get('server:shutdownTimeout'));
|
stoppable(self.httpServer, config.get('server:shutdownTimeout'));
|
||||||
|
|
||||||
async function shutdown() {
|
|
||||||
try {
|
|
||||||
logging.warn(i18n.t('notices.httpServer.ghostIsShuttingDown'));
|
|
||||||
await self.stop();
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
logging.error(error);
|
|
||||||
process.exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that Ghost exits correctly on Ctrl+C and SIGTERM
|
// ensure that Ghost exits correctly on Ctrl+C and SIGTERM
|
||||||
process
|
process
|
||||||
.removeAllListeners('SIGINT').on('SIGINT', shutdown)
|
.removeAllListeners('SIGINT').on('SIGINT', self.shutdown.bind(self))
|
||||||
.removeAllListeners('SIGTERM').on('SIGTERM', shutdown);
|
.removeAllListeners('SIGTERM').on('SIGTERM', self.shutdown.bind(self));
|
||||||
|
|
||||||
if (config.get('server:testmode')) {
|
if (config.get('server:testmode')) {
|
||||||
// Debug code
|
// Debug code
|
||||||
|
@ -138,48 +126,68 @@ class GhostServer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ### Shutdown
|
||||||
|
* Stops the server, handles cleanup and exits the process = a full shutdown
|
||||||
|
* Called on SIGINT or SIGTERM
|
||||||
|
*/
|
||||||
|
async shutdown() {
|
||||||
|
try {
|
||||||
|
logging.warn(i18n.t('notices.httpServer.ghostIsShuttingDown'));
|
||||||
|
await this.stop();
|
||||||
|
process.exit(0);
|
||||||
|
} catch (error) {
|
||||||
|
logging.error(error);
|
||||||
|
process.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ### Stop
|
* ### Stop
|
||||||
* Returns a promise that will be fulfilled when the server stops. If the server has not been started,
|
* Stops the server & handles cleanup, but does not exit the process
|
||||||
* the promise will be fulfilled immediately
|
* Used in tests for quick start/stop actions
|
||||||
|
* Called by shutdown to handle server stop and cleanup before exiting
|
||||||
* @returns {Promise} Resolves once Ghost has stopped
|
* @returns {Promise} Resolves once Ghost has stopped
|
||||||
*/
|
*/
|
||||||
stop() {
|
async stop() {
|
||||||
const self = this;
|
if (this.httpServer === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
await this._stopServer();
|
||||||
if (self.httpServer === null) {
|
events.emit('server.stop');
|
||||||
resolve(self);
|
this.httpServer = null;
|
||||||
} else {
|
this._logStopMessages();
|
||||||
// The stop function comes from stoppable
|
|
||||||
self.httpServer.stop(function (err) {
|
|
||||||
if (err) {
|
|
||||||
reject(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
events.emit('server.stop');
|
|
||||||
self.httpServer = null;
|
|
||||||
self.logStopMessages();
|
|
||||||
resolve(self);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ### Hammertime
|
* ### Hammertime
|
||||||
* To be called after `stop`
|
* To be called after `stop`
|
||||||
*/
|
*/
|
||||||
hammertime() {
|
async hammertime() {
|
||||||
logging.info(i18n.t('notices.httpServer.cantTouchThis'));
|
logging.info(i18n.t('notices.httpServer.cantTouchThis'));
|
||||||
|
}
|
||||||
|
|
||||||
return Promise.resolve(this);
|
/**
|
||||||
|
* ### Stop Server
|
||||||
|
* Does the work of stopping the server using stoppable
|
||||||
|
* This handles closing connections:
|
||||||
|
* - New connections are rejected
|
||||||
|
* - Idle connections are closed immediately
|
||||||
|
* - Active connections are allowed to complete in-flight requests before being closed
|
||||||
|
*
|
||||||
|
* If server.shutdownTimeout is reached, requests are terminated in-flight
|
||||||
|
*/
|
||||||
|
async _stopServer() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.httpServer.stop((err, status) => (err ? reject(err) : resolve(status)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ### Log Start Messages
|
* ### Log Start Messages
|
||||||
*/
|
*/
|
||||||
logStartMessages() {
|
_logStartMessages() {
|
||||||
logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
|
logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
|
||||||
|
|
||||||
if (config.get('env') === 'production') {
|
if (config.get('env') === 'production') {
|
||||||
|
@ -197,8 +205,9 @@ class GhostServer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ### Log Stop Messages
|
* ### Log Stop Messages
|
||||||
|
* Private / internal API
|
||||||
*/
|
*/
|
||||||
logStopMessages() {
|
_logStopMessages() {
|
||||||
logging.warn(i18n.t('notices.httpServer.ghostHasShutdown'));
|
logging.warn(i18n.t('notices.httpServer.ghostHasShutdown'));
|
||||||
|
|
||||||
// Extra clear message for production mode
|
// Extra clear message for production mode
|
||||||
|
|
Loading…
Add table
Reference in a new issue