mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Moved notify out of GhostServer
- make this a standalone module
This commit is contained in:
parent
b65cb7bd7b
commit
2527efd6fc
5 changed files with 90 additions and 74 deletions
23
core/boot.js
23
core/boot.js
|
@ -187,6 +187,19 @@ function mountGhost(rootApp, ghostApp) {
|
||||||
debug('End: mountGhost');
|
debug('End: mountGhost');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @TODO: make this notification different
|
||||||
|
function notifyReadiness(error) {
|
||||||
|
const notify = require('./server/notify');
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
debug('Notifying readiness (error)');
|
||||||
|
notify.notifyServerStarted(error);
|
||||||
|
} else {
|
||||||
|
debug('Notifying readiness (success)');
|
||||||
|
notify.notifyServerStarted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ----------------------------------
|
* ----------------------------------
|
||||||
* Boot Ghost - The magic starts here
|
* Boot Ghost - The magic starts here
|
||||||
|
@ -255,9 +268,8 @@ async function bootGhost() {
|
||||||
|
|
||||||
// We are technically done here
|
// We are technically done here
|
||||||
bootLogger.log('booted');
|
bootLogger.log('booted');
|
||||||
// @TODO: make this notification different
|
|
||||||
// debug('boot notifying readiness');
|
notifyReadiness();
|
||||||
// GhostServer.notifyServerStarted();
|
|
||||||
|
|
||||||
// Init our background jobs, we don't wait for this to finish
|
// Init our background jobs, we don't wait for this to finish
|
||||||
initRecurringJobs({config});
|
initRecurringJobs({config});
|
||||||
|
@ -267,8 +279,7 @@ async function bootGhost() {
|
||||||
return ghostServer;
|
return ghostServer;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errors = require('@tryghost/errors');
|
const errors = require('@tryghost/errors');
|
||||||
// @TODO: fix these extra requires
|
// @TODO: fix this extra require
|
||||||
const GhostServer = require('./server/ghost-server');
|
|
||||||
const logging = require('./shared/logging');
|
const logging = require('./shared/logging');
|
||||||
|
|
||||||
let serverStartError = error;
|
let serverStartError = error;
|
||||||
|
@ -278,7 +289,7 @@ async function bootGhost() {
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.error(serverStartError);
|
logging.error(serverStartError);
|
||||||
GhostServer.notifyServerStarted(serverStartError);
|
notifyReadiness(serverStartError);
|
||||||
|
|
||||||
// If ghost was started and something else went wrong, we shut it down
|
// If ghost was started and something else went wrong, we shut it down
|
||||||
if (ghostServer) {
|
if (ghostServer) {
|
||||||
|
|
|
@ -11,8 +11,8 @@ const urlUtils = require('./../shared/url-utils');
|
||||||
const errors = require('@tryghost/errors');
|
const errors = require('@tryghost/errors');
|
||||||
const {i18n} = require('./lib/common');
|
const {i18n} = require('./lib/common');
|
||||||
const logging = require('../shared/logging');
|
const logging = require('../shared/logging');
|
||||||
|
const notify = require('./notify');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
|
||||||
const stoppable = require('stoppable');
|
const stoppable = require('stoppable');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,7 +109,7 @@ class GhostServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
debug('server notifying started');
|
debug('server notifying started');
|
||||||
return GhostServer.notifyServerStarted()
|
return notify.notifyServerStarted()
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
resolve(self);
|
resolve(self);
|
||||||
});
|
});
|
||||||
|
@ -288,55 +288,3 @@ class GhostServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = GhostServer;
|
module.exports = GhostServer;
|
||||||
|
|
||||||
/**
|
|
||||||
* We call notify server started when the server is ready to serve traffic
|
|
||||||
* When the server is started, but not ready, it is only able to serve 503s
|
|
||||||
*
|
|
||||||
* If the server isn't able to reach started, notifyServerStarted is called with an error
|
|
||||||
* A status message, any error, and debug info are all passed to managing processes via IPC and the bootstrap socket
|
|
||||||
*/
|
|
||||||
let notifyServerStartedCalled = false;
|
|
||||||
|
|
||||||
const debugInfo = {
|
|
||||||
versions: process.versions,
|
|
||||||
platform: process.platform,
|
|
||||||
arch: process.arch,
|
|
||||||
release: process.release
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.notifyServerStarted = function (error = null) {
|
|
||||||
// If we already sent a ready notification, we should not do it again
|
|
||||||
if (notifyServerStartedCalled) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark this function as called
|
|
||||||
notifyServerStartedCalled = true;
|
|
||||||
|
|
||||||
// Build our message
|
|
||||||
// - if there's no error then the server is ready
|
|
||||||
let message = {
|
|
||||||
started: true,
|
|
||||||
debug: debugInfo
|
|
||||||
};
|
|
||||||
|
|
||||||
// - if there's an error then the server is not ready, include the errors
|
|
||||||
if (error) {
|
|
||||||
message.started = false;
|
|
||||||
message.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CASE: IPC communication to the CLI for local process manager
|
|
||||||
if (process.send) {
|
|
||||||
process.send(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CASE: use bootstrap socket to communicate with CLI for systemd
|
|
||||||
let socketAddress = config.get('bootstrap-socket');
|
|
||||||
if (socketAddress) {
|
|
||||||
return bootstrapSocket.connectAndSend(socketAddress, logging, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
};
|
|
||||||
|
|
57
core/server/notify.js
Normal file
57
core/server/notify.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* We call notify server started when the server is ready to serve traffic
|
||||||
|
* When the server is started, but not ready, it is only able to serve 503s
|
||||||
|
*
|
||||||
|
* If the server isn't able to reach started, notifyServerStarted is called with an error
|
||||||
|
* A status message, any error, and debug info are all passed to managing processes via IPC and the bootstrap socket
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Required Ghost internals
|
||||||
|
const config = require('../shared/config');
|
||||||
|
const logging = require('../shared/logging');
|
||||||
|
|
||||||
|
let notifyServerStartedCalled = false;
|
||||||
|
|
||||||
|
const debugInfo = {
|
||||||
|
versions: process.versions,
|
||||||
|
platform: process.platform,
|
||||||
|
arch: process.arch,
|
||||||
|
release: process.release
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.notifyServerStarted = function (error = null) {
|
||||||
|
// If we already sent a ready notification, we should not do it again
|
||||||
|
if (notifyServerStartedCalled) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark this function as called
|
||||||
|
notifyServerStartedCalled = true;
|
||||||
|
|
||||||
|
// Build our message
|
||||||
|
// - if there's no error then the server is ready
|
||||||
|
let message = {
|
||||||
|
started: true,
|
||||||
|
debug: debugInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
// - if there's an error then the server is not ready, include the errors
|
||||||
|
if (error) {
|
||||||
|
message.started = false;
|
||||||
|
message.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASE: IPC communication to the CLI for local process manager
|
||||||
|
if (process.send) {
|
||||||
|
process.send(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASE: use bootstrap socket to communicate with CLI for systemd
|
||||||
|
let socketAddress = config.get('bootstrap-socket');
|
||||||
|
if (socketAddress) {
|
||||||
|
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
||||||
|
return bootstrapSocket.connectAndSend(socketAddress, logging, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
|
@ -6,16 +6,16 @@ const {events} = require('../../../core/server/lib/common');
|
||||||
|
|
||||||
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
||||||
|
|
||||||
describe('GhostServer', function () {
|
describe('Notify', function () {
|
||||||
describe('notifyServerStarted', function () {
|
describe('notifyServerStarted', function () {
|
||||||
let GhostServer;
|
let notify;
|
||||||
let socketStub;
|
let socketStub;
|
||||||
let eventSpy;
|
let eventSpy;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
// Have to re-require each time to clear the internal flag
|
// Have to re-require each time to clear the internal flag
|
||||||
delete require.cache[require.resolve('../../../core/server/ghost-server')];
|
delete require.cache[require.resolve('../../../core/server/notify')];
|
||||||
GhostServer = require('../../../core/server/ghost-server');
|
notify = require('../../../core/server/notify');
|
||||||
|
|
||||||
// process.send isn't set for tests, we can safely override;
|
// process.send isn't set for tests, we can safely override;
|
||||||
process.send = sinon.stub();
|
process.send = sinon.stub();
|
||||||
|
@ -35,11 +35,11 @@ describe('GhostServer', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it resolves a promise', function () {
|
it('it resolves a promise', function () {
|
||||||
GhostServer.notifyServerStarted().should.be.fulfilled();
|
notify.notifyServerStarted().should.be.fulfilled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it communicates with IPC correctly on success', function () {
|
it('it communicates with IPC correctly on success', function () {
|
||||||
GhostServer.notifyServerStarted();
|
notify.notifyServerStarted();
|
||||||
|
|
||||||
process.send.calledOnce.should.be.true();
|
process.send.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ describe('GhostServer', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('communicates with IPC correctly on failure', function () {
|
it('communicates with IPC correctly on failure', function () {
|
||||||
GhostServer.notifyServerStarted(new Error('something went wrong'));
|
notify.notifyServerStarted(new Error('something went wrong'));
|
||||||
|
|
||||||
process.send.calledOnce.should.be.true();
|
process.send.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ describe('GhostServer', function () {
|
||||||
it('communicates via bootstrap socket correctly on success', function () {
|
it('communicates via bootstrap socket correctly on success', function () {
|
||||||
configUtils.set('bootstrap-socket', 'testing');
|
configUtils.set('bootstrap-socket', 'testing');
|
||||||
|
|
||||||
GhostServer.notifyServerStarted();
|
notify.notifyServerStarted();
|
||||||
|
|
||||||
socketStub.calledOnce.should.be.true();
|
socketStub.calledOnce.should.be.true();
|
||||||
socketStub.firstCall.args[0].should.eql('testing');
|
socketStub.firstCall.args[0].should.eql('testing');
|
||||||
|
@ -79,7 +79,7 @@ describe('GhostServer', function () {
|
||||||
it('communicates via bootstrap socket correctly on failure', function () {
|
it('communicates via bootstrap socket correctly on failure', function () {
|
||||||
configUtils.set('bootstrap-socket', 'testing');
|
configUtils.set('bootstrap-socket', 'testing');
|
||||||
|
|
||||||
GhostServer.notifyServerStarted(new Error('something went wrong'));
|
notify.notifyServerStarted(new Error('something went wrong'));
|
||||||
|
|
||||||
socketStub.calledOnce.should.be.true();
|
socketStub.calledOnce.should.be.true();
|
||||||
socketStub.firstCall.args[0].should.eql('testing');
|
socketStub.firstCall.args[0].should.eql('testing');
|
||||||
|
@ -95,9 +95,9 @@ describe('GhostServer', function () {
|
||||||
it('can be called multiple times, but only communicates once', function () {
|
it('can be called multiple times, but only communicates once', function () {
|
||||||
configUtils.set('bootstrap-socket', 'testing');
|
configUtils.set('bootstrap-socket', 'testing');
|
||||||
|
|
||||||
GhostServer.notifyServerStarted();
|
notify.notifyServerStarted();
|
||||||
GhostServer.notifyServerStarted(new Error('something went wrong'));
|
notify.notifyServerStarted(new Error('something went wrong'));
|
||||||
GhostServer.notifyServerStarted();
|
notify.notifyServerStarted();
|
||||||
|
|
||||||
process.send.calledOnce.should.be.true();
|
process.send.calledOnce.should.be.true();
|
||||||
socketStub.calledOnce.should.be.true();
|
socketStub.calledOnce.should.be.true();
|
|
@ -14,10 +14,10 @@ const knexMigrator = new KnexMigrator();
|
||||||
// Ghost Internals
|
// Ghost Internals
|
||||||
const config = require('../../core/shared/config');
|
const config = require('../../core/shared/config');
|
||||||
const boot = require('../../core/boot');
|
const boot = require('../../core/boot');
|
||||||
const GhostServer = require('../../core/server/ghost-server');
|
|
||||||
const {events} = require('../../core/server/lib/common');
|
const {events} = require('../../core/server/lib/common');
|
||||||
const db = require('../../core/server/data/db');
|
const db = require('../../core/server/data/db');
|
||||||
const models = require('../../core/server/models');
|
const models = require('../../core/server/models');
|
||||||
|
const notify = require('../../core/server/notify');
|
||||||
const urlService = require('../../core/frontend/services/url');
|
const urlService = require('../../core/frontend/services/url');
|
||||||
const settingsService = require('../../core/server/services/settings');
|
const settingsService = require('../../core/server/services/settings');
|
||||||
const frontendSettingsService = require('../../core/frontend/services/settings');
|
const frontendSettingsService = require('../../core/frontend/services/settings');
|
||||||
|
@ -252,7 +252,7 @@ const freshModeGhostStart = async (options) => {
|
||||||
await bootGhost(options);
|
await bootGhost(options);
|
||||||
|
|
||||||
// Ensure notify was called (this is idempotent)
|
// Ensure notify was called (this is idempotent)
|
||||||
GhostServer.notifyServerStarted();
|
notify.notifyServerStarted();
|
||||||
|
|
||||||
// Wait for the URL service to be ready, which happens after boot, but don't re-trigger db.ready
|
// Wait for the URL service to be ready, which happens after boot, but don't re-trigger db.ready
|
||||||
await urlServiceUtils.isFinished({disableDbReadyEvent: true});
|
await urlServiceUtils.isFinished({disableDbReadyEvent: true});
|
||||||
|
|
Loading…
Add table
Reference in a new issue