0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

🎨 ⏱ Cleanup / optimise the server.init() function (#7985)

refs #2182

* 🔥 Remove unused options from server init
- this is left over from old code and is now unused

* 🎨 Move knex-migrator check to db health

- Move complex check function into own module
- Call module from server/index.js
- This just improves the readability of server/index.js

* 🔥 Remove old comments

- These comments all make no sense now!

* 🎨 ⏱ Move model init out of promise chain

- Model.init() does not return a promise
- Therefore, we can move it to the top of the init function, outside of the promise change
- This should be a minor optimisation, and again improves readability /clarity of what's happening

*  ⁉️ Move DBHash init / first run to Settings model

- this structure is left over from when we had code we executed on the first run of Ghost
- the implementation used the API to initialise one setting before populateDefaults is called
- this had lots of dependencies - the whole model, API, and permissions structure had to be initialised for it to work
- the new implementation is simpler, it captures the dbHash getting initialised during populateDefaults()
- it also adds an event, so we can do first-run code later if we really want to (or maybe apps can?!)
- perhaps this is hiding behaviour, and there's a nicer way to do it, but populateDefaults seems like a sane place to populate a default setting 😁

* ⏱ Optimise require order so config is first

- the first require to config will cause the files to be read etc
- this ensures that it happens early, and isn't confusingly timed as part of loading a different module

* 🎨 Simplify settings model changes
This commit is contained in:
Hannah Wolfe 2017-02-17 16:44:34 +00:00 committed by Katharina Irrgang
parent 9bd50cb527
commit b00d9fee6d
3 changed files with 64 additions and 81 deletions

View file

@ -0,0 +1,40 @@
var KnexMigrator = require('knex-migrator'),
config = require('../../config'),
errors = require('../../errors'),
models = require('../../models');
module.exports.check = function healthCheck() {
var knexMigrator = new KnexMigrator({
knexMigratorFilePath: config.get('paths:appRoot')
});
return knexMigrator.isDatabaseOK()
.catch(function (outerErr) {
if (outerErr.code === 'DB_NOT_INITIALISED') {
throw outerErr;
}
// CASE: migration table does not exist, figure out if database is compatible
return models.Settings.findOne({key: 'databaseVersion', context: {internal: true}})
.then(function (response) {
// CASE: no db version key, database is compatible
if (!response) {
throw outerErr;
}
throw new errors.DatabaseVersionError({
message: 'Your database version is not compatible with Ghost 1.0.0 Alpha (master branch)',
context: 'Want to keep your DB? Use Ghost < 1.0.0 or the "stable" branch. Otherwise please delete your DB and restart Ghost.',
help: 'More information on the Ghost 1.0.0 Alpha at https://support.ghost.org/v1-0-alpha'
});
})
.catch(function (err) {
// CASE: settings table does not exist
if (err.errno === 1 || err.errno === 1146) {
throw outerErr;
}
throw err;
});
});
};

View file

@ -14,122 +14,57 @@ require('./overrides');
// Module dependencies
var debug = require('debug')('ghost:boot:init'),
uuid = require('uuid'),
Promise = require('bluebird'),
KnexMigrator = require('knex-migrator'),
// Config should be first require, as it triggers the initial load of the config files
config = require('./config'),
Promise = require('bluebird'),
logging = require('./logging'),
errors = require('./errors'),
i18n = require('./i18n'),
api = require('./api'),
models = require('./models'),
permissions = require('./permissions'),
apps = require('./apps'),
auth = require('./auth'),
dbHealth = require('./data/db/health'),
xmlrpc = require('./data/xml/xmlrpc'),
slack = require('./data/slack'),
GhostServer = require('./ghost-server'),
scheduling = require('./scheduling'),
readDirectory = require('./utils/read-directory'),
utils = require('./utils'),
knexMigrator = new KnexMigrator({
knexMigratorFilePath: config.get('paths:appRoot')
}),
dbHash;
function initDbHashAndFirstRun() {
return api.settings.read({key: 'dbHash', context: {internal: true}}).then(function (response) {
var hash = response.settings[0].value,
initHash;
dbHash = hash;
if (dbHash === null) {
initHash = uuid.v4();
return api.settings.edit({settings: [{key: 'dbHash', value: initHash}]}, {context: {internal: true}})
.then(function (response) {
dbHash = response.settings[0].value;
return dbHash;
// Use `then` here to do 'first run' actions
});
}
return dbHash;
});
}
utils = require('./utils');
// ## Initialise Ghost
// Sets up the express server instances, runs init on a bunch of stuff, configures views, helpers, routes and more
// Finally it returns an instance of GhostServer
function init(options) {
function init() {
debug('Init Start...');
options = options || {};
var ghostServer, parentApp;
// ### Initialisation
// The server and its dependencies require a populated config
// It returns a promise that is resolved when the application
// has finished starting up.
// Initialize Internationalization
i18n.init();
debug('I18n done');
models.init();
debug('models done');
return readDirectory(config.getContentPath('apps')).then(function loadThemes(result) {
config.set('paths:availableApps', result);
return api.themes.loadThemes();
}).then(function () {
debug('Themes & apps done');
models.init();
}).then(function () {
return knexMigrator.isDatabaseOK()
.catch(function (outerErr) {
if (outerErr.code === 'DB_NOT_INITIALISED') {
throw outerErr;
}
// CASE: migration table does not exist, figure out if database is compatible
return models.Settings.findOne({key: 'databaseVersion', context: {internal: true}})
.then(function (response) {
// CASE: no db version key, database is compatible
if (!response) {
throw outerErr;
}
throw new errors.DatabaseVersionError({
message: 'Your database version is not compatible with Ghost 1.0.0 Alpha (master branch)',
context: 'Want to keep your DB? Use Ghost < 1.0.0 or the "stable" branch. Otherwise please delete your DB and restart Ghost.',
help: 'More information on the Ghost 1.0.0 Alpha at https://support.ghost.org/v1-0-alpha'
});
})
.catch(function (err) {
// CASE: settings table does not exist
if (err.errno === 1 || err.errno === 1146) {
throw outerErr;
}
throw err;
});
});
return dbHealth.check();
}).then(function () {
debug('DB health check done');
// Populate any missing default settings
return models.Settings.populateDefaults();
}).then(function () {
debug('Models & database done');
// Refresh the API settings cache
return api.settings.updateSettingsCache();
}).then(function () {
debug('Update settings cache done');
// Initialize the permissions actions and objects
// NOTE: Must be done before initDbHashAndFirstRun calls
return permissions.init();
}).then(function () {
debug('Permissions done');
return Promise.join(
// Check for or initialise a dbHash.
initDbHashAndFirstRun(),
// Initialize apps
apps.init(),
// Initialize xmrpc ping

View file

@ -1,12 +1,14 @@
var Settings,
ghostBookshelf = require('./base'),
_ = require('lodash'),
errors = require('../errors'),
Promise = require('bluebird'),
validation = require('../data/validation'),
_ = require('lodash'),
uuid = require('uuid'),
ghostBookshelf = require('./base'),
errors = require('../errors'),
events = require('../events'),
internalContext = {context: {internal: true}},
i18n = require('../i18n'),
validation = require('../data/validation'),
internalContext = {context: {internal: true}},
defaultSettings;
@ -15,12 +17,18 @@ var Settings,
// instead of iterating those categories every time
function parseDefaultSettings() {
var defaultSettingsInCategories = require('../data/schema/').defaultSettings,
defaultSettingsFlattened = {};
defaultSettingsFlattened = {},
dynamicDefault = {
dbHash: uuid.v4()
};
_.each(defaultSettingsInCategories, function each(settings, categoryName) {
_.each(settings, function each(setting, settingName) {
setting.type = categoryName;
setting.key = settingName;
if (dynamicDefault[setting.key]) {
setting.defaultValue = dynamicDefault[setting.key];
}
defaultSettingsFlattened[settingName] = setting;
});