mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 15:44:59 +00:00
Merge pull request #24 from wistityhq/feature/restart
Restart the server in development and production
This commit is contained in:
commit
a93db78104
@ -8,6 +8,7 @@
|
||||
|
||||
// Node.js core.
|
||||
const REPL = require('repl');
|
||||
const cluster = require('cluster');
|
||||
|
||||
// Public node modules.
|
||||
const winston = require('winston');
|
||||
@ -36,7 +37,12 @@ module.exports = function () {
|
||||
|
||||
// Now load up the Strapi framework for real.
|
||||
const strapi = server();
|
||||
strapi.log.info('Starting the application in interactive mode...');
|
||||
|
||||
// Only log if the process is a master.
|
||||
if (cluster.isMaster) {
|
||||
strapi.log.info('Starting the application in interactive mode...');
|
||||
}
|
||||
|
||||
strapi.start({}, function (err) {
|
||||
|
||||
// Log and exit the REPL in case there is an error
|
||||
|
||||
@ -41,7 +41,7 @@ function Strapi() {
|
||||
this.load = _.bind(this.load, this);
|
||||
this.start = _.bind(this.start, this);
|
||||
this.stop = _.bind(this.stop, this);
|
||||
this.rebuild = _.bind(this.rebuild, this);
|
||||
this.restart = _.bind(this.restart, this);
|
||||
this.initialize = _.bind(this.initialize, this);
|
||||
this.exposeGlobals = _.bind(this.exposeGlobals, this);
|
||||
this.runBootstrap = _.bind(this.runBootstrap, this);
|
||||
@ -81,7 +81,7 @@ util.inherits(Strapi, events.EventEmitter);
|
||||
|
||||
Strapi.prototype.start = require('./start');
|
||||
Strapi.prototype.stop = require('./stop');
|
||||
Strapi.prototype.rebuild = require('./rebuild');
|
||||
Strapi.prototype.restart = require('./restart');
|
||||
Strapi.prototype.server = require('koa');
|
||||
Strapi.prototype.app = require('koa')();
|
||||
|
||||
|
||||
@ -170,21 +170,6 @@ module.exports = function (strapi) {
|
||||
});
|
||||
|
||||
cb();
|
||||
},
|
||||
|
||||
/**
|
||||
* Reload the hook
|
||||
*/
|
||||
|
||||
reload: function () {
|
||||
hook.initialize(function (err) {
|
||||
if (err) {
|
||||
strapi.log.error('Failed to reinitialize the API hook.');
|
||||
strapi.stop();
|
||||
} else {
|
||||
strapi.emit('hook:_api:reloaded');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -111,13 +111,6 @@ module.exports = function (strapi) {
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure the ORM config are equals to the databases file
|
||||
// (aiming to not have issue with adapters when rebuilding the dictionary).
|
||||
// It's kind of messy, for now, but it works fine. If someone has a better
|
||||
// solution we'd be glad to accept a Pull Request.
|
||||
const ormConfig = JSON.parse(fs.readFileSync(path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments', strapi.config.environment, 'databases.json')));
|
||||
strapi.config.orm = ormConfig.orm;
|
||||
|
||||
// Save different environments inside an array because we need it in the Strapi Studio.
|
||||
strapi.config.environments = fs.readdirSync(path.resolve(strapi.config.appPath, strapi.config.paths.config, 'environments'));
|
||||
|
||||
@ -131,21 +124,6 @@ module.exports = function (strapi) {
|
||||
});
|
||||
|
||||
cb();
|
||||
},
|
||||
|
||||
/**
|
||||
* Reload the hook
|
||||
*/
|
||||
|
||||
reload: function () {
|
||||
hook.initialize(function (err) {
|
||||
if (err) {
|
||||
strapi.log.error('Failed to reinitialize the config hook.');
|
||||
strapi.stop();
|
||||
} else {
|
||||
strapi.emit('hook:_config:reloaded');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -141,21 +141,6 @@ module.exports = function (strapi) {
|
||||
});
|
||||
|
||||
cb();
|
||||
},
|
||||
|
||||
/**
|
||||
* Reload the hook
|
||||
*/
|
||||
|
||||
reload: function () {
|
||||
hook.initialize(function (err) {
|
||||
if (err) {
|
||||
strapi.log.error('Failed to reinitialize the router.');
|
||||
strapi.stop();
|
||||
} else {
|
||||
strapi.emit('hook:router:reloaded');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -62,188 +62,189 @@ module.exports = function (strapi) {
|
||||
]
|
||||
});
|
||||
|
||||
manager.on('connect_failed', function () {
|
||||
if (firstConnectionAttempt) {
|
||||
strapi.log.warn('Connection to the Studio server failed!');
|
||||
}
|
||||
});
|
||||
|
||||
manager.on('reconnect_failed', function () {
|
||||
strapi.log.warn('Reconnection to the Studio server failed!');
|
||||
});
|
||||
|
||||
manager.on('reconnect', function () {
|
||||
strapi.log.info('Connection to the Studio server found, please wait a few seconds...');
|
||||
});
|
||||
|
||||
manager.on('reconnecting', function (number) {
|
||||
strapi.log.warn('Connection error with the Studio server, new attempt in progress... (' + number + ')');
|
||||
});
|
||||
|
||||
socket.on('connect', function () {
|
||||
strapi.log.info('Connection with the Studio server found, please wait a few seconds...');
|
||||
firstConnectionAttempt = false;
|
||||
process.nextTick(_self.connectWithStudio(socket));
|
||||
});
|
||||
|
||||
socket.on('error', function (err) {
|
||||
strapi.log.warn(err);
|
||||
});
|
||||
|
||||
socket.on('disconnect', function () {
|
||||
strapi.log.info('Disconnected from the Studio server.');
|
||||
});
|
||||
|
||||
socket.on('authorized', function (data) {
|
||||
const decryptedData = strapi.rsa.decryptPublic(data, 'json');
|
||||
|
||||
if (decryptedData.status === 'ok') {
|
||||
if (strapi.config.environment === 'development') {
|
||||
socket.emit('testEncryption', {
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
secretKey: strapi.config.studio.secretKey,
|
||||
data: 'ok'
|
||||
})
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
strapi.log.warn(err);
|
||||
}
|
||||
|
||||
strapi.log.info('Connected with the Studio server.');
|
||||
});
|
||||
} else {
|
||||
strapi.log.warn('The use of the Studio is restricted to development environment.');
|
||||
process.nextTick(function () {
|
||||
manager.on('connect_failed', function () {
|
||||
if (firstConnectionAttempt) {
|
||||
strapi.log.warn('Connection to the Studio server failed!');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('todo', function (data, fn) {
|
||||
if (!data.hasOwnProperty('from') || !data.hasOwnProperty('to')) {
|
||||
fn(stringify('Some required attributes are missing', null, 2), null);
|
||||
} else if (data.from === strapi.token) {
|
||||
if (data.hasOwnProperty('files')) {
|
||||
const syncPromise = function (file, index) {
|
||||
const deferred = Promise.defer();
|
||||
manager.on('reconnect_failed', function () {
|
||||
strapi.log.warn('Reconnection to the Studio server failed!');
|
||||
});
|
||||
|
||||
_self.unzipper(file)
|
||||
.then(function () {
|
||||
if (!_.isEmpty(data.files[index + 1])) {
|
||||
return syncPromise(data.files[index + 1], index + 1);
|
||||
} else {
|
||||
manager.on('reconnect', function () {
|
||||
strapi.log.info('Connection to the Studio server found, please wait a few seconds...');
|
||||
});
|
||||
|
||||
manager.on('reconnecting', function (number) {
|
||||
strapi.log.warn('Connection error with the Studio server, new attempt in progress... (' + number + ')');
|
||||
});
|
||||
|
||||
socket.on('connect', function () {
|
||||
firstConnectionAttempt = false;
|
||||
_self.connectWithStudio(socket);
|
||||
});
|
||||
|
||||
socket.on('error', function (err) {
|
||||
strapi.log.warn(err);
|
||||
});
|
||||
|
||||
socket.on('disconnect', function () {
|
||||
strapi.log.info('Disconnected from the Studio server.');
|
||||
});
|
||||
|
||||
socket.on('authorized', function (data) {
|
||||
const decryptedData = strapi.rsa.decryptPublic(data, 'json');
|
||||
|
||||
if (decryptedData.status === 'ok') {
|
||||
if (strapi.config.environment === 'development') {
|
||||
socket.emit('testEncryption', {
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
secretKey: strapi.config.studio.secretKey,
|
||||
data: 'ok'
|
||||
})
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
strapi.log.warn(err);
|
||||
}
|
||||
|
||||
strapi.log.info('Connected with the Studio server.');
|
||||
});
|
||||
} else {
|
||||
strapi.log.warn('The use of the Studio is restricted to development environment.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('todo', function (data, fn) {
|
||||
if (!data.hasOwnProperty('from') || !data.hasOwnProperty('to')) {
|
||||
fn(stringify('Some required attributes are missing', null, 2), null);
|
||||
} else if (data.from === strapi.token) {
|
||||
if (data.hasOwnProperty('files')) {
|
||||
const syncPromise = function (file, index) {
|
||||
const deferred = Promise.defer();
|
||||
|
||||
_self.unzipper(file)
|
||||
.then(function () {
|
||||
if (!_.isEmpty(data.files[index + 1])) {
|
||||
return syncPromise(data.files[index + 1], index + 1);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
deferred.resolve();
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(function (err) {
|
||||
deferred.reject(err);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
syncPromise(_.first(data.files), 0)
|
||||
.then(function () {
|
||||
deferred.resolve();
|
||||
})
|
||||
.catch(function (err) {
|
||||
deferred.reject(err);
|
||||
});
|
||||
if (data.hasOwnProperty('action') && _.isFunction(_self[data.action])) {
|
||||
_self[data.action](data, function (err, obj) {
|
||||
if (err) {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: stringify(err, null, 2),
|
||||
data: null
|
||||
})
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
syncPromise(_.first(data.files), 0)
|
||||
.then(function () {
|
||||
if (data.hasOwnProperty('action') && _.isFunction(_self[data.action])) {
|
||||
_self[data.action](data, function (err, obj) {
|
||||
if (err) {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: stringify(err, null, 2),
|
||||
data: null
|
||||
err: null,
|
||||
data: stringify(obj, null, 2)
|
||||
})
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
} else if (!data.hasOwnProperty('action')) {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: null,
|
||||
data: stringify(obj, null, 2)
|
||||
data: stringify(true, null, 2)
|
||||
})
|
||||
});
|
||||
});
|
||||
} else if (!data.hasOwnProperty('action')) {
|
||||
} else {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: stringify('Unknow action', null, 2),
|
||||
data: null
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: null,
|
||||
data: stringify(true, null, 2)
|
||||
})
|
||||
});
|
||||
} else {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: stringify('Unknow action', null, 2),
|
||||
err: err,
|
||||
data: null
|
||||
})
|
||||
});
|
||||
});
|
||||
} else if (!data.hasOwnProperty('action')) {
|
||||
fn(strapi.rsa.encrypt(stringify('`action` attribute is missing', null, 2)), strapi.rsa.encryptPrivate(null));
|
||||
} else if (_.isFunction(_self[data.action])) {
|
||||
_self[data.action](data, function (err, obj) {
|
||||
if (err) {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: err,
|
||||
data: null
|
||||
})
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: err,
|
||||
data: null
|
||||
err: null,
|
||||
data: stringify(obj, null, 2)
|
||||
})
|
||||
});
|
||||
});
|
||||
} else if (!data.hasOwnProperty('action')) {
|
||||
fn(strapi.rsa.encrypt(stringify('`action` attribute is missing', null, 2)), strapi.rsa.encryptPrivate(null));
|
||||
} else if (_.isFunction(_self[data.action])) {
|
||||
_self[data.action](data, function (err, obj) {
|
||||
if (err) {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: err,
|
||||
data: null
|
||||
})
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: null,
|
||||
data: stringify(obj, null, 2)
|
||||
err: stringify('Unknow action', null, 2),
|
||||
data: null
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
fn({
|
||||
appId: strapi.config.studio.appId,
|
||||
token: strapi.token,
|
||||
encrypted: strapi.rsa.encrypt({
|
||||
err: stringify('Unknow action', null, 2),
|
||||
data: null
|
||||
})
|
||||
});
|
||||
fn(stringify('Bad user token', null, 2), null);
|
||||
}
|
||||
} else {
|
||||
fn(stringify('Bad user token', null, 2), null);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('err', function (data) {
|
||||
strapi.log.warn(data.text);
|
||||
socket.on('err', function (data) {
|
||||
strapi.log.warn(data.text);
|
||||
});
|
||||
});
|
||||
|
||||
cb();
|
||||
@ -263,28 +264,27 @@ module.exports = function (strapi) {
|
||||
if (err) {
|
||||
strapi.log.warn('Continuing without credentials.');
|
||||
} else {
|
||||
strapi.log.info('Connection with the Studio server found, please wait a few seconds...');
|
||||
|
||||
config = JSON.parse(config);
|
||||
strapi.token = config.token;
|
||||
|
||||
socket.emit('getPublicKey', null, function (publicKey) {
|
||||
if (publicKey) {
|
||||
if (publicKey && strapi.config.environment === 'development') {
|
||||
const key = new RSA();
|
||||
let object;
|
||||
key.importKey(publicKey, 'public');
|
||||
|
||||
if (strapi.config.environment === 'development') {
|
||||
object = {
|
||||
appId: strapi.config.studio.appId,
|
||||
appName: strapi.config.name,
|
||||
publicKey: strapi.rsa.exportKey('private'),
|
||||
secretKey: strapi.config.studio.secretKey,
|
||||
dashboardToken: strapi.config.dashboard.token,
|
||||
token: strapi.token,
|
||||
env: strapi.config.environment
|
||||
};
|
||||
const object = {
|
||||
appId: strapi.config.studio.appId,
|
||||
appName: strapi.config.name,
|
||||
publicKey: strapi.rsa.exportKey('private'),
|
||||
secretKey: strapi.config.studio.secretKey,
|
||||
dashboardToken: strapi.config.dashboard.token,
|
||||
token: strapi.token,
|
||||
env: strapi.config.environment
|
||||
};
|
||||
|
||||
socket.emit('check', key.encrypt(object));
|
||||
}
|
||||
socket.emit('check', key.encrypt(object));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -334,7 +334,7 @@ module.exports = function (strapi) {
|
||||
*/
|
||||
|
||||
rebuild: function (data, cb) {
|
||||
strapi.rebuild();
|
||||
strapi.restart();
|
||||
|
||||
cb(null, true);
|
||||
},
|
||||
|
||||
@ -10,7 +10,6 @@ const spawn = require('child_process').spawnSync;
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const Waterline = require('waterline');
|
||||
const WaterlineGraphQL = require('waterline-graphql');
|
||||
|
||||
@ -199,43 +198,6 @@ module.exports = function (strapi) {
|
||||
}
|
||||
|
||||
cb();
|
||||
},
|
||||
|
||||
/**
|
||||
* Reload the hook
|
||||
*/
|
||||
|
||||
reload: function () {
|
||||
hook.teardown(function () {
|
||||
hook.initialize(function (err) {
|
||||
if (err) {
|
||||
strapi.log.error('Failed to reinitialize the ORM hook.');
|
||||
strapi.stop();
|
||||
} else {
|
||||
strapi.emit('hook:waterline:reloaded');
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Teardown adapters
|
||||
*/
|
||||
|
||||
teardown: function (cb) {
|
||||
cb = cb || function (err) {
|
||||
if (err) {
|
||||
strapi.log.error('Failed to teardown ORM adapters.');
|
||||
strapi.stop();
|
||||
}
|
||||
};
|
||||
async.forEach(Object.keys(strapi.adapters || {}), function (name, next) {
|
||||
if (strapi.adapters[name].teardown) {
|
||||
strapi.adapters[name].teardown(null, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}, cb);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -55,6 +55,12 @@ module.exports = function (strapi) {
|
||||
// Make the environment in config match the server one.
|
||||
environment: strapi.app.env || process.env.NODE_ENV,
|
||||
|
||||
// Default reload config.
|
||||
reload: {
|
||||
timeout: 1000,
|
||||
workers: 1
|
||||
},
|
||||
|
||||
// Default paths.
|
||||
paths: {
|
||||
tmp: '.tmp',
|
||||
@ -74,8 +80,9 @@ module.exports = function (strapi) {
|
||||
url: 'http://studio.strapi.io'
|
||||
},
|
||||
|
||||
// Start off needed empty objects.
|
||||
routes: {}
|
||||
// Start off needed empty objects and strings.
|
||||
routes: {},
|
||||
frontendUrl: ''
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
14
lib/load.js
14
lib/load.js
@ -7,6 +7,7 @@
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const herd = require('herd');
|
||||
|
||||
// Local dependencies.
|
||||
const __Configuration = require('./configuration');
|
||||
@ -140,7 +141,18 @@ module.exports = function (strapi) {
|
||||
}
|
||||
|
||||
// We can finally make the server listen on the configured port.
|
||||
strapi.app.listen(strapi.config.port);
|
||||
// Use of the `herd` node module to herd the child processes with
|
||||
// zero downtime reloads.
|
||||
if (_.isPlainObject(strapi.config.reload) && !_.isEmpty(strapi.config.reload) && strapi.config.reload.workers > 0) {
|
||||
herd(strapi.config.name)
|
||||
.timeout(strapi.config.reload.timeout)
|
||||
.size(strapi.config.reload.workers)
|
||||
.run(function () {
|
||||
strapi.app.listen(strapi.config.port);
|
||||
});
|
||||
} else {
|
||||
strapi.app.listen(strapi.config.port);
|
||||
}
|
||||
|
||||
cb && cb(null, strapi);
|
||||
};
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Node.js core.
|
||||
const cluster = require('cluster');
|
||||
|
||||
/**
|
||||
* `strapi.prototype.initialize()`
|
||||
*
|
||||
@ -52,16 +59,19 @@ module.exports = function initialize(cb) {
|
||||
}
|
||||
});
|
||||
|
||||
// Run the application bootstrap.
|
||||
self.runBootstrap(function afterBootstrap(err) {
|
||||
if (err) {
|
||||
self.log.error('Bootstrap encountered an error.');
|
||||
return cb(self.log.error(err));
|
||||
}
|
||||
// Only run the application bootstrap if
|
||||
// we are in a master cluster.
|
||||
if (cluster.isMaster) {
|
||||
self.runBootstrap(function afterBootstrap(err) {
|
||||
if (err) {
|
||||
self.log.error('Bootstrap encountered an error.');
|
||||
return cb(self.log.error(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// And fire the `ready` event.
|
||||
// This is listened to by attached servers, etc.
|
||||
self.emit('ready');
|
||||
cb(null, self);
|
||||
});
|
||||
// And fire the `ready` event.
|
||||
// This is listened to by attached servers, etc.
|
||||
self.emit('ready');
|
||||
cb(null, self);
|
||||
};
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const cluster = require('cluster');
|
||||
|
||||
// Local dependencies.
|
||||
const __hooks = require('../configuration/hooks');
|
||||
@ -30,6 +31,12 @@ module.exports = function (strapi) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not load the `studio` hook if the
|
||||
// cluster is not the master.
|
||||
if (!cluster.isMaster) {
|
||||
delete hooks.studio;
|
||||
}
|
||||
|
||||
// Handle folder-defined modules (default to `lib/index.js`)
|
||||
// Since a hook definition must be a function.
|
||||
if (_.isObject(hookPrototype) && !_.isArray(hookPrototype) && !_.isFunction(hookPrototype)) {
|
||||
|
||||
@ -1,74 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Public node modules.
|
||||
const async = require('async');
|
||||
|
||||
/**
|
||||
* Load the application dictionary
|
||||
*/
|
||||
|
||||
module.exports = function () {
|
||||
const self = this;
|
||||
|
||||
console.log();
|
||||
self.log.debug('Rebuilding application dictionary...');
|
||||
|
||||
// Update the Strapi status (might be used
|
||||
// by the core or some hooks).
|
||||
self.reloading = true;
|
||||
|
||||
// Async module loader to rebuild a
|
||||
// dictionary of the application.
|
||||
async.auto({
|
||||
|
||||
// Rebuild the dictionaries.
|
||||
dictionaries: function (cb) {
|
||||
self.hooks._config.reload();
|
||||
self.hooks._api.reload();
|
||||
cb();
|
||||
},
|
||||
|
||||
// Make sure to delete the router stack.
|
||||
router: function (cb) {
|
||||
delete self.router;
|
||||
cb();
|
||||
}
|
||||
},
|
||||
|
||||
// Callback.
|
||||
function (err) {
|
||||
|
||||
// Just in case there is an error.
|
||||
if (err) {
|
||||
self.log.error('Impossible to reload the server');
|
||||
self.log.error('Please restart the server manually');
|
||||
self.stop();
|
||||
}
|
||||
|
||||
// Tell the application the framework is reloading
|
||||
// (might be used by some hooks).
|
||||
self.reloading = true;
|
||||
|
||||
// Teardown Waterline adapters and
|
||||
// reload the Waterline ORM.
|
||||
self.log.debug('Reloading the ORM...');
|
||||
self.hooks.waterline.reload();
|
||||
|
||||
// Reloading the router.
|
||||
self.log.debug('Reloading the router...');
|
||||
self.hooks.router.reload();
|
||||
|
||||
// Update `strapi` status.
|
||||
self.reloaded = true;
|
||||
self.reloading = false;
|
||||
|
||||
// Finally inform the developer everything seems ok.
|
||||
self.log.info('Dictionary successfully rebuilt');
|
||||
self.log.warn('You still need to restart your server to fully enjoy changes...');
|
||||
console.log();
|
||||
});
|
||||
};
|
||||
22
lib/restart.js
Normal file
22
lib/restart.js
Normal file
@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Node.js core.
|
||||
const cluster = require('cluster');
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
/**
|
||||
* Programmatically restart the server
|
||||
* (useful for the Studio)
|
||||
*/
|
||||
|
||||
module.exports = function () {
|
||||
_.forEach(cluster.worker, function () {
|
||||
process.kill(process.pid, 'SIGHUP');
|
||||
});
|
||||
};
|
||||
24
lib/start.js
24
lib/start.js
@ -4,6 +4,9 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
// Node.js core.
|
||||
const cluster = require('cluster');
|
||||
|
||||
// Public node modules.
|
||||
const async = require('async');
|
||||
|
||||
@ -44,12 +47,21 @@ module.exports = function start(configOverride, cb) {
|
||||
}
|
||||
|
||||
// Log some server info.
|
||||
self.log.info('Server started in ' + self.config.appPath);
|
||||
self.log.info('Your server is running at ' + self.config.url);
|
||||
self.log.info('Time: ' + new Date());
|
||||
self.log.info('Environment: ' + self.config.environment);
|
||||
self.log.info('Process PID: ' + process.pid);
|
||||
self.log.info('To shut down your server, press <CTRL> + C at any time');
|
||||
if (cluster.isMaster) {
|
||||
self.log.info('Server started in ' + self.config.appPath);
|
||||
self.log.info('Your server is running at ' + self.config.url);
|
||||
self.log.debug('Time: ' + new Date());
|
||||
self.log.debug('Environment: ' + self.config.environment);
|
||||
self.log.debug('Process PID: ' + process.pid);
|
||||
self.log.debug('Cluster: master');
|
||||
self.log.info('To shut down your server, press <CTRL> + C at any time');
|
||||
} else {
|
||||
self.log.warn('New worker starting...');
|
||||
self.log.debug('Process PID: ' + process.pid);
|
||||
self.log.debug('Cluster: worker #' + cluster.worker.id);
|
||||
}
|
||||
|
||||
// Blank log to give some space.
|
||||
console.log();
|
||||
|
||||
// Emit an event when Strapi has started.
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
"consolidate": "^0.13.1",
|
||||
"fs-extra": "^0.24.0",
|
||||
"graphql": "^0.4.9",
|
||||
"herd": "^1.0.0",
|
||||
"include-all": "^0.1.6",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"koa": "^1.1.0",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user