2017-08-02 21:24:01 +00:00
|
|
|
'use strict'
|
|
|
|
import config from '../scripts/load-config.js'
|
|
|
|
import Logger from '../scripts/logger.js'
|
|
|
|
import cluster from 'cluster'
|
|
|
|
import path from 'path'
|
|
|
|
|
|
|
|
const cpuCount = require('os').cpus().length
|
|
|
|
const workers = []
|
|
|
|
const logger = new Logger()
|
|
|
|
|
|
|
|
const args = {
|
|
|
|
dev: process.env.NODE_ENV !== 'production',
|
|
|
|
port: config.server.port
|
|
|
|
}
|
|
|
|
|
2017-08-26 14:14:45 +00:00
|
|
|
function spawnWorkers () {
|
2020-05-28 18:30:21 +00:00
|
|
|
const workerCount = config.server.workers === 0 ? cpuCount : config.server.workers
|
2017-12-01 11:35:47 +00:00
|
|
|
console.log('Spinning up %d worker process%s', workerCount, (workerCount !== 1 ? 'es' : ''))
|
2017-08-26 14:14:45 +00:00
|
|
|
|
|
|
|
for (let i = 0; i < workerCount; i++) {
|
|
|
|
spawnWorker()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-02 21:24:01 +00:00
|
|
|
async function initialize () {
|
|
|
|
try {
|
|
|
|
const knex = require('knex')(require('../knexfile'))
|
|
|
|
console.log('Initializing database...')
|
|
|
|
await knex.migrate.latest()
|
|
|
|
console.log('Database initialized')
|
|
|
|
await knex.destroy()
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Database error:', err)
|
|
|
|
}
|
|
|
|
|
2017-08-26 14:14:45 +00:00
|
|
|
spawnWorkers()
|
|
|
|
if (args.dev) {
|
|
|
|
watchFileTree()
|
2017-08-02 21:24:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-26 14:14:45 +00:00
|
|
|
function watchFileTree () {
|
|
|
|
if (process.argv.indexOf('-w') === -1) return
|
|
|
|
console.log('[WatchTask] Starting watcher')
|
|
|
|
|
|
|
|
const watch = require('watch')
|
|
|
|
watch.watchTree(__dirname, (f, curr, prev) => {
|
|
|
|
if (typeof f === 'object' && prev === null && curr === null) {
|
|
|
|
console.log('[WatchTask] Watching %d files', Object.keys(f).length)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('[WatchTask] %s changed, restarting workers', f)
|
|
|
|
if (workers.length) {
|
2020-05-28 18:30:21 +00:00
|
|
|
for (const i in workers) {
|
2017-08-26 14:14:45 +00:00
|
|
|
workers[i].send('stop')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spawnWorkers()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-08-02 21:24:01 +00:00
|
|
|
function spawnWorker (oldWorker) {
|
|
|
|
const w = cluster.fork()
|
|
|
|
w.process.stdout.on('data', (data) => {
|
|
|
|
console.log(w.process.pid, data.toString().trim())
|
|
|
|
})
|
|
|
|
w.process.stderr.on('data', (data) => {
|
|
|
|
console.log(w.process.pid, data.toString().trim())
|
|
|
|
})
|
2017-12-01 11:35:47 +00:00
|
|
|
args.verbose && console.log('Starting worker process %d...', w.process.pid)
|
2017-08-02 21:24:01 +00:00
|
|
|
|
|
|
|
w.on('message', (message) => {
|
|
|
|
if (message === 'started') {
|
|
|
|
workers.push(w)
|
2017-12-01 11:35:47 +00:00
|
|
|
args.verbose && console.log('Started worker process', w.process.pid)
|
2017-08-02 21:24:01 +00:00
|
|
|
if (oldWorker) {
|
2017-12-01 11:35:47 +00:00
|
|
|
args.verbose && console.log('Stopping worker process', oldWorker.process.pid)
|
2017-08-02 21:24:01 +00:00
|
|
|
oldWorker.send('stop')
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
logger.logProcess(w.process.pid, message)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
args.id = w.process.pid
|
|
|
|
|
|
|
|
w.send(args)
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('Initializing')
|
|
|
|
|
|
|
|
cluster.setupMaster({
|
|
|
|
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
|
|
exec: path.join(__dirname, './worker.js')
|
|
|
|
})
|
|
|
|
|
|
|
|
cluster.on('exit', (worker, code, signal) => {
|
2020-05-28 18:30:21 +00:00
|
|
|
const extra = ((code || '') + ' ' + (signal || '')).trim()
|
2017-08-02 21:24:01 +00:00
|
|
|
|
2017-12-01 11:35:47 +00:00
|
|
|
console.error('Worker process %d exited %s', worker.process.pid, (extra ? '(' + extra + ')' : ''))
|
2017-08-02 21:24:01 +00:00
|
|
|
|
2020-05-28 18:30:21 +00:00
|
|
|
const index = workers.indexOf(worker)
|
2017-08-02 21:24:01 +00:00
|
|
|
|
|
|
|
if (index !== -1) workers.splice(index, 1)
|
|
|
|
if (code === 0) return
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
spawnWorker()
|
|
|
|
}, 10 * 1000)
|
|
|
|
})
|
|
|
|
|
|
|
|
initialize()
|
2017-08-31 09:53:05 +00:00
|
|
|
|
|
|
|
process.stdin.resume()
|
|
|
|
|
|
|
|
process.on('SIGUSR2', () => {
|
|
|
|
console.log('Received SIGUSR2. Restarting workers.')
|
|
|
|
|
|
|
|
if (workers.length) {
|
2020-05-28 18:30:21 +00:00
|
|
|
for (const i in workers) {
|
2017-08-31 09:53:05 +00:00
|
|
|
workers[i].send('stop')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
spawnWorkers()
|
|
|
|
})
|