0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Add promise to ghost startup process to allow

hooking into when ghost has finished loading

addresses item 9 in #2078
and makes progress on #2182

- has files that startup ghost return a promise
 that is resolved once ghost has finished loading
- moves getSocket into config file
- removes models.reset() as it's not used anywhere
- update functions in server startup
- remove unused version hash variable
This commit is contained in:
Harry Wolff 2014-02-19 22:22:02 -05:00
parent c4d4f66a38
commit 3e21940b18
5 changed files with 143 additions and 129 deletions

View file

@ -2,17 +2,31 @@
// Orchestrates the loading of Ghost
// When run from command line.
var bootstrap = require('./bootstrap'),
errors = require('./server/errorHandling');
var when = require('when'),
bootstrap = require('./bootstrap');
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
function startGhost(options) {
// When we no longer need to require('./server')
// in a callback this extra deferred object
// won't be necessary, we'll just be able to return
// the server object directly.
var deferred = when.defer();
options = options || {};
bootstrap(options.config).then(function () {
var ghost = require('./server');
ghost(options.app);
}).otherwise(errors.logAndThrowError);
return ghost(options.app).then(deferred.resolve).otherwise(function (e) {
// We don't return the rejected promise to stop
// the propogation of the rejection and just
// allow the user to manage what to do.
deferred.reject(e);
});
});
return deferred.promise;
}
module.exports = startGhost;

View file

@ -14,6 +14,14 @@ var path = require('path'),
appRoot = path.resolve(__dirname, '../../../'),
corePath = path.resolve(appRoot, 'core/');
// Are we using sockets? Custom socket or the default?
function getSocket() {
if (ghostConfig.server.hasOwnProperty('socket')) {
return _.isString(ghostConfig.server.socket) ? ghostConfig.server.socket : path.join(ghostConfig.paths.contentPath, process.env.NODE_ENV + '.socket');
}
return false;
}
function updateConfig(config) {
var localPath,
contentPath,
@ -110,5 +118,6 @@ function config() {
module.exports = config;
module.exports.init = initConfig;
module.exports.theme = theme;
module.exports.getSocket = getSocket;
module.exports.urlFor = configUrl.urlFor;
module.exports.urlForPost = configUrl.urlForPost;

View file

@ -4,7 +4,6 @@ var crypto = require('crypto'),
hbs = require('express-hbs'),
fs = require('fs'),
uuid = require('node-uuid'),
path = require('path'),
Polyglot = require('node-polyglot'),
semver = require('semver'),
_ = require('lodash'),
@ -22,7 +21,6 @@ var crypto = require('crypto'),
routes = require('./routes'),
packageInfo = require('../../package.json'),
// Variables
dbHash;
@ -107,21 +105,92 @@ function builtFilesExist() {
return when.all(deferreds);
}
function startGhost(deferred) {
return function () {
// Tell users if their node version is not supported, and exit
if (!semver.satisfies(process.versions.node, packageInfo.engines.node)) {
console.log(
"\nERROR: Unsupported version of Node".red,
"\nGhost needs Node version".red,
packageInfo.engines.node.yellow,
"you are using version".red,
process.versions.node.yellow,
"\nPlease go to http://nodejs.org to get a supported version".green
);
process.exit(0);
}
// Startup & Shutdown messages
if (process.env.NODE_ENV === 'production') {
console.log(
"Ghost is running...".green,
"\nYour blog is now available on",
config().url,
"\nCtrl+C to shut down".grey
);
// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nGhost has shut down".red,
"\nYour blog is now offline"
);
process.exit(0);
});
} else {
console.log(
("Ghost is running in " + process.env.NODE_ENV + "...").green,
"\nListening on",
config.getSocket() || config().server.host + ':' + config().server.port,
"\nUrl configured as:",
config().url,
"\nCtrl+C to shut down".grey
);
// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nGhost has shutdown".red,
"\nGhost was running for",
Math.round(process.uptime()),
"seconds"
);
process.exit(0);
});
}
deferred.resolve();
};
}
// ## Initializes the ghost application.
// Sets up the express server instance.
// Instantiates the ghost singleton, helpers, routes, middleware, and apps.
// Finally it starts the http server.
function setup(server) {
function init(server) {
// create a hash for cache busting assets
var assetHash = (crypto.createHash('md5').update(packageInfo.version + Date.now()).digest('hex')).substring(0, 10);
// If no express instance is passed in
// then create our own
if (!server) {
server = express();
}
// Set up Polygot instance on the require module
Polyglot.instance = new Polyglot();
// ### Initialisation
// The server and its dependencies require a populated config
// It returns a promise that is resolved when the application
// has finished starting up.
// Initialise the models
models.init().then(function () {
// Make sure javascript files have been built via grunt concat
return builtFilesExist().then(function () {
// Initialise the models
return models.init();
}).then(function () {
// Populate any missing default settings
return models.Settings.populateDefaults();
}).then(function () {
@ -136,19 +205,17 @@ function setup(server) {
// Check for or initialise a dbHash.
initDbHashAndFirstRun(),
// Initialize the permissions actions and objects
permissions.init()
permissions.init(),
// Initialize mail
mailer.init(),
// Initialize apps
apps.init()
);
}).then(function () {
// Make sure javascript files have been built via grunt concat
return builtFilesExist();
}).then(function () {
// Initialize mail
return mailer.init();
}).then(function () {
var adminHbs = hbs.create();
var adminHbs = hbs.create(),
deferred = when.defer();
// ##Configuration
server.set('version hash', assetHash);
// return the correct mime type for woff filess
express['static'].mime.define({'application/font-woff': ['woff']});
@ -177,111 +244,37 @@ function setup(server) {
// Set up Frontend routes
routes.frontend(server);
// Are we using sockets? Custom socket or the default?
function getSocket() {
if (config().server.hasOwnProperty('socket')) {
return _.isString(config().server.socket) ? config().server.socket : path.join(config.path().contentPath, process.env.NODE_ENV + '.socket');
}
return false;
}
function startGhost() {
// Tell users if their node version is not supported, and exit
if (!semver.satisfies(process.versions.node, packageInfo.engines.node)) {
console.log(
"\nERROR: Unsupported version of Node".red,
"\nGhost needs Node version".red,
packageInfo.engines.node.yellow,
"you are using version".red,
process.versions.node.yellow,
"\nPlease go to http://nodejs.org to get a supported version".green
);
process.exit(0);
}
// Startup & Shutdown messages
if (process.env.NODE_ENV === 'production') {
console.log(
"Ghost is running...".green,
"\nYour blog is now available on",
config().url,
"\nCtrl+C to shut down".grey
);
// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nGhost has shut down".red,
"\nYour blog is now offline"
);
process.exit(0);
});
} else {
console.log(
("Ghost is running in " + process.env.NODE_ENV + "...").green,
"\nListening on",
getSocket() || config().server.host + ':' + config().server.port,
"\nUrl configured as:",
config().url,
"\nCtrl+C to shut down".grey
);
// ensure that Ghost exits correctly on Ctrl+C
process.on('SIGINT', function () {
console.log(
"\nGhost has shutdown".red,
"\nGhost was running for",
Math.round(process.uptime()),
"seconds"
);
process.exit(0);
});
}
}
// Initialize apps then start the server
apps.init().then(function () {
// ## Start Ghost App
if (getSocket()) {
// Make sure the socket is gone before trying to create another
fs.unlink(getSocket(), function (err) {
/*jshint unused:false*/
server.listen(
getSocket(),
startGhost
);
fs.chmod(getSocket(), '0660');
});
} else {
server.listen(
config().server.port,
config().server.host,
startGhost
);
}
_.each(config().paths.availableThemes._messages.errors, function (error) {
errors.logError(error.message, error.context);
});
_.each(config().paths.availableThemes._messages.warns, function (warn) {
errors.logWarn(warn.message, warn.context);
});
// Log all theme errors and warnings
_.each(config().paths.availableThemes._messages.errors, function (error) {
errors.logError(error.message, error.context);
});
}, function (err) {
errors.logErrorAndExit(err, err.context, err.help);
_.each(config().paths.availableThemes._messages.warns, function (warn) {
errors.logWarn(warn.message, warn.context);
});
// ## Start Ghost App
if (config.getSocket()) {
// Make sure the socket is gone before trying to create another
fs.unlink(config.getSocket(), function (err) {
/*jshint unused:false*/
server.listen(
config.getSocket(),
startGhost(deferred)
);
fs.chmod(config.getSocket(), '0660');
});
} else {
server.listen(
config().server.port,
config().server.host,
startGhost(deferred)
);
}
return deferred.promise;
});
}
// Initializes the ghost application.
function init(app) {
if (!app) {
app = express();
}
// The server and its dependencies require a populated config
setup(app);
}
module.exports = init;

View file

@ -14,11 +14,6 @@ module.exports = {
init: function () {
return migrations.init();
},
reset: function () {
return migrations.reset().then(function () {
return migrations.init();
});
},
// ### deleteAllContent
// Delete all content from the database (posts, tags, tags_posts)
deleteAllContent: function () {

View file

@ -2,6 +2,9 @@
// Orchestrates the loading of Ghost
// When run from command line.
var ghost = require('./core');
var ghost = require('./core'),
errors = require('./core/server/errorHandling');
ghost();
ghost().otherwise(function (err) {
errors.logErrorAndExit(err, err.context, err.help);
});