feat: Kernel module
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
// ===========================================
|
||||
// Wiki.js
|
||||
// Licensed under AGPLv3
|
||||
@@ -13,7 +11,8 @@ let wiki = {
|
||||
IS_MASTER: cluster.isMaster,
|
||||
ROOTPATH: process.cwd(),
|
||||
SERVERPATH: path.join(process.cwd(), 'server'),
|
||||
configSvc: require('./modules/config')
|
||||
configSvc: require('./modules/config'),
|
||||
kernel: require('./modules/kernel')
|
||||
}
|
||||
global.wiki = wiki
|
||||
|
||||
@@ -38,37 +37,7 @@ wiki.logger = require('./modules/logger').init()
|
||||
wiki.db = require('./modules/db').init()
|
||||
|
||||
// ----------------------------------------
|
||||
// Start Cluster
|
||||
// Start Kernel
|
||||
// ----------------------------------------
|
||||
|
||||
const numCPUs = require('os').cpus().length
|
||||
let numWorkers = (wiki.config.workers > 0) ? wiki.config.workers : numCPUs
|
||||
if (numWorkers > numCPUs) {
|
||||
numWorkers = numCPUs
|
||||
}
|
||||
|
||||
if (cluster.isMaster) {
|
||||
wiki.logger.info('=======================================')
|
||||
wiki.logger.info('= Wiki.js =============================')
|
||||
wiki.logger.info('=======================================')
|
||||
|
||||
require('./master').then(() => {
|
||||
// -> Create background workers
|
||||
for (let i = 0; i < numWorkers; i++) {
|
||||
cluster.fork()
|
||||
}
|
||||
|
||||
// -> Queue post-init tasks
|
||||
|
||||
wiki.queue.uplClearTemp.add({}, {
|
||||
repeat: { cron: '*/15 * * * *' }
|
||||
})
|
||||
})
|
||||
|
||||
cluster.on('exit', (worker, code, signal) => {
|
||||
wiki.logger.info(`Background Worker #${worker.id} was terminated.`)
|
||||
})
|
||||
} else {
|
||||
wiki.logger.info(`Background Worker #${cluster.worker.id} is initializing...`)
|
||||
require('./worker')
|
||||
}
|
||||
wiki.kernel.init()
|
||||
|
@@ -1,90 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const Promise = require('bluebird')
|
||||
const fs = Promise.promisifyAll(require('fs-extra'))
|
||||
const pm2 = Promise.promisifyAll(require('pm2'))
|
||||
const ora = require('ora')
|
||||
const path = require('path')
|
||||
|
||||
const ROOTPATH = process.cwd()
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Detect the most appropriate start mode
|
||||
*/
|
||||
startDetect: function () {
|
||||
if (process.env.WIKI_JS_HEROKU) {
|
||||
return this.startInHerokuMode()
|
||||
} else {
|
||||
return this.startInBackgroundMode()
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Start in background mode
|
||||
*/
|
||||
startInBackgroundMode: function () {
|
||||
let spinner = ora('Initializing...').start()
|
||||
return fs.emptyDirAsync(path.join(ROOTPATH, './logs')).then(() => {
|
||||
return pm2.connectAsync().then(() => {
|
||||
return pm2.startAsync({
|
||||
name: 'wiki',
|
||||
script: 'server',
|
||||
cwd: ROOTPATH,
|
||||
output: path.join(ROOTPATH, './logs/wiki-output.log'),
|
||||
error: path.join(ROOTPATH, './logs/wiki-error.log'),
|
||||
minUptime: 5000,
|
||||
maxRestarts: 5
|
||||
}).then(() => {
|
||||
spinner.succeed('Wiki.js has started successfully.')
|
||||
}).finally(() => {
|
||||
pm2.disconnect()
|
||||
})
|
||||
})
|
||||
}).catch(err => {
|
||||
spinner.fail(err)
|
||||
process.exit(1)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Start in Heroku mode
|
||||
*/
|
||||
startInHerokuMode: function () {
|
||||
console.warn('Incorrect command on Heroku, use instead: node server')
|
||||
process.exit(1)
|
||||
},
|
||||
/**
|
||||
* Stop Wiki.js process(es)
|
||||
*/
|
||||
stop () {
|
||||
let spinner = ora('Shutting down Wiki.js...').start()
|
||||
return pm2.connectAsync().then(() => {
|
||||
return pm2.stopAsync('wiki').then(() => {
|
||||
spinner.succeed('Wiki.js has stopped successfully.')
|
||||
}).finally(() => {
|
||||
pm2.disconnect()
|
||||
})
|
||||
}).catch(err => {
|
||||
spinner.fail(err)
|
||||
process.exit(1)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Restart Wiki.js process(es)
|
||||
*/
|
||||
restart: function () {
|
||||
let self = this
|
||||
return self.stop().delay(1000).then(() => {
|
||||
self.startDetect()
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Start the web-based configuration wizard
|
||||
*
|
||||
* @param {Number} port Port to bind the HTTP server on
|
||||
*/
|
||||
configure (port) {
|
||||
port = port || 3000
|
||||
let spinner = ora('Initializing interactive setup...').start()
|
||||
require('./configure')(port, spinner)
|
||||
}
|
||||
}
|
@@ -1,17 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
const Promise = require('bluebird')
|
||||
|
||||
wiki.redis = require('./modules/redis').init()
|
||||
wiki.queue = require('./modules/queue').init()
|
||||
|
||||
module.exports = Promise.join(
|
||||
wiki.db.onReady,
|
||||
wiki.configSvc.loadFromDb(),
|
||||
wiki.queue.clean()
|
||||
).then(() => {
|
||||
module.exports = () => {
|
||||
// ----------------------------------------
|
||||
// Load global modules
|
||||
// ----------------------------------------
|
||||
@@ -194,7 +183,4 @@ module.exports = Promise.join(
|
||||
})
|
||||
|
||||
return true
|
||||
}).catch(err => {
|
||||
wiki.logger.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ module.exports = (sequelize, DataTypes) => {
|
||||
}
|
||||
},
|
||||
provider: {
|
||||
type: DataTypes.ENUM(wiki.data.authProviders),
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
providerId: {
|
||||
@@ -37,6 +37,15 @@ module.exports = (sequelize, DataTypes) => {
|
||||
role: {
|
||||
type: DataTypes.ENUM('admin', 'user', 'guest'),
|
||||
allowNull: false
|
||||
},
|
||||
tfaIsActive: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: false
|
||||
},
|
||||
tfaSecret: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true
|
||||
}
|
||||
}, {
|
||||
timestamps: true,
|
||||
|
@@ -75,13 +75,14 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
}).then(results => {
|
||||
if (_.isArray(results) && results.length > 0) {
|
||||
if (_.isArray(results) && results.length === subsets.length) {
|
||||
results.forEach(result => {
|
||||
wiki.config[result.key] = result.config
|
||||
})
|
||||
return true
|
||||
} else {
|
||||
return Promise.reject(new Error('Invalid DB Configuration result set'))
|
||||
wiki.logger.warn('DB Configuration is empty or incomplete.')
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -75,7 +75,7 @@ module.exports = {
|
||||
min: 0,
|
||||
idle: 10000
|
||||
},
|
||||
logging: false,
|
||||
logging: log => { wiki.logger.log('verbose', log) },
|
||||
operatorsAliases
|
||||
})
|
||||
|
||||
@@ -92,10 +92,10 @@ module.exports = {
|
||||
|
||||
fs
|
||||
.readdirSync(dbModelsPath)
|
||||
.filter(function (file) {
|
||||
.filter(file => {
|
||||
return (file.indexOf('.') !== 0 && file.indexOf('_') !== 0)
|
||||
})
|
||||
.forEach(function (file) {
|
||||
.forEach(file => {
|
||||
let modelName = _.upperFirst(_.camelCase(_.split(file, '.')[0]))
|
||||
self[modelName] = self.inst.import(path.join(dbModelsPath, file))
|
||||
})
|
||||
@@ -110,8 +110,8 @@ module.exports = {
|
||||
// -> Sync DB Schemas
|
||||
syncSchemas() {
|
||||
return self.inst.sync({
|
||||
force: false,
|
||||
logging: false
|
||||
force: true,
|
||||
logging: log => { wiki.logger.log('verbose', log) }
|
||||
})
|
||||
},
|
||||
// -> Set Connection App Name
|
||||
@@ -129,7 +129,7 @@ module.exports = {
|
||||
|
||||
// Perform init tasks
|
||||
|
||||
self.onReady = Promise.each(initTasksQueue, t => t())
|
||||
self.onReady = Promise.each(initTasksQueue, t => t()).return(true)
|
||||
|
||||
return self
|
||||
}
|
||||
|
91
server/modules/kernel.js
Normal file
91
server/modules/kernel.js
Normal file
@@ -0,0 +1,91 @@
|
||||
const cluster = require('cluster')
|
||||
const Promise = require('bluebird')
|
||||
const _ = require('lodash')
|
||||
|
||||
/* global wiki */
|
||||
|
||||
module.exports = {
|
||||
numWorkers: 1,
|
||||
workers: [],
|
||||
init() {
|
||||
if (cluster.isMaster) {
|
||||
wiki.logger.info('=======================================')
|
||||
wiki.logger.info('= Wiki.js =============================')
|
||||
wiki.logger.info('=======================================')
|
||||
|
||||
wiki.redis = require('./redis').init()
|
||||
wiki.queue = require('./queue').init()
|
||||
|
||||
this.setWorkerLimit()
|
||||
this.bootMaster()
|
||||
} else {
|
||||
this.bootWorker()
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Pre-Master Boot Sequence
|
||||
*/
|
||||
preBootMaster() {
|
||||
return Promise.mapSeries([
|
||||
() => { return wiki.db.onReady },
|
||||
() => { return wiki.configSvc.loadFromDb() },
|
||||
() => { return wiki.queue.clean() }
|
||||
], fn => { return fn() })
|
||||
},
|
||||
/**
|
||||
* Boot Master Process
|
||||
*/
|
||||
bootMaster() {
|
||||
this.preBootMaster().then(sequenceResults => {
|
||||
if (_.every(sequenceResults, rs => rs === true)) {
|
||||
this.postBootMaster()
|
||||
} else {
|
||||
wiki.logger.info('Starting configuration manager...')
|
||||
require('../configure')()
|
||||
}
|
||||
return true
|
||||
}).catch(err => {
|
||||
wiki.logger.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Post-Master Boot Sequence
|
||||
*/
|
||||
postBootMaster() {
|
||||
require('../master')().then(() => {
|
||||
_.times(this.numWorker, this.spawnWorker)
|
||||
|
||||
wiki.queue.uplClearTemp.add({}, {
|
||||
repeat: { cron: '*/15 * * * *' }
|
||||
})
|
||||
})
|
||||
|
||||
cluster.on('exit', (worker, code, signal) => {
|
||||
wiki.logger.info(`Background Worker #${worker.id} was terminated.`)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Boot Worker Process
|
||||
*/
|
||||
bootWorker() {
|
||||
wiki.logger.info(`Background Worker #${cluster.worker.id} is initializing...`)
|
||||
require('../worker')
|
||||
},
|
||||
/**
|
||||
* Spawn new Worker process
|
||||
*/
|
||||
spawnWorker() {
|
||||
this.workers.push(cluster.fork())
|
||||
},
|
||||
/**
|
||||
* Set Worker count based on config + system capabilities
|
||||
*/
|
||||
setWorkerLimit() {
|
||||
const numCPUs = require('os').cpus().length
|
||||
this.numWorkers = (wiki.config.workers > 0) ? wiki.config.workers : numCPUs
|
||||
if (this.numWorkers > numCPUs) {
|
||||
this.numWorkers = numCPUs
|
||||
}
|
||||
}
|
||||
}
|
@@ -30,7 +30,7 @@ module.exports = {
|
||||
})
|
||||
}).then(() => {
|
||||
wiki.logger.info('Purging old queue jobs: OK')
|
||||
}).catch(err => {
|
||||
}).return(true).catch(err => {
|
||||
wiki.logger.error(err)
|
||||
})
|
||||
}
|
||||
|
@@ -1,5 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
const Promise = require('bluebird')
|
||||
|
Reference in New Issue
Block a user