diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
| commit | 0e4a111f81cceed275d9bec2695f6e401fb654d8 (patch) | |
| tree | 40874799472fa07416f17b50a398ac33b7771905 /src/boot | |
| parent | update deps (diff) | |
| download | sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.gz sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.bz2 sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.zip | |
refactoring
Resolve #7779
Diffstat (limited to 'src/boot')
| -rw-r--r-- | src/boot/index.ts | 79 | ||||
| -rw-r--r-- | src/boot/master.ts | 194 | ||||
| -rw-r--r-- | src/boot/worker.ts | 20 |
3 files changed, 0 insertions, 293 deletions
diff --git a/src/boot/index.ts b/src/boot/index.ts deleted file mode 100644 index cb4c8536db..0000000000 --- a/src/boot/index.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as cluster from 'cluster'; -import * as chalk from 'chalk'; -import Xev from 'xev'; - -import Logger from '@/services/logger'; -import { envOption } from '../env'; - -// for typeorm -import 'reflect-metadata'; -import { masterMain } from './master'; -import { workerMain } from './worker'; - -const logger = new Logger('core', 'cyan'); -const clusterLogger = logger.createSubLogger('cluster', 'orange', false); -const ev = new Xev(); - -/** - * Init process - */ -export default async function() { - process.title = `Misskey (${cluster.isMaster ? 'master' : 'worker'})`; - - if (cluster.isMaster || envOption.disableClustering) { - await masterMain(); - - if (cluster.isMaster) { - ev.mount(); - } - } - - if (cluster.isWorker || envOption.disableClustering) { - await workerMain(); - } - - // ユニットテスト時にMisskeyが子プロセスで起動された時のため - // それ以外のときは process.send は使えないので弾く - if (process.send) { - process.send('ok'); - } -} - -//#region Events - -// Listen new workers -cluster.on('fork', worker => { - clusterLogger.debug(`Process forked: [${worker.id}]`); -}); - -// Listen online workers -cluster.on('online', worker => { - clusterLogger.debug(`Process is now online: [${worker.id}]`); -}); - -// Listen for dying workers -cluster.on('exit', worker => { - // Replace the dead worker, - // we're not sentimental - clusterLogger.error(chalk.red(`[${worker.id}] died :(`)); - cluster.fork(); -}); - -// Display detail of unhandled promise rejection -if (!envOption.quiet) { - process.on('unhandledRejection', console.dir); -} - -// Display detail of uncaught exception -process.on('uncaughtException', err => { - try { - logger.error(err); - } catch { } -}); - -// Dying away... -process.on('exit', code => { - logger.info(`The process is going to exit with code ${code}`); -}); - -//#endregion diff --git a/src/boot/master.ts b/src/boot/master.ts deleted file mode 100644 index 071b37b76d..0000000000 --- a/src/boot/master.ts +++ /dev/null @@ -1,194 +0,0 @@ -import * as fs from 'fs'; -import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import * as os from 'os'; -import * as cluster from 'cluster'; -import * as chalk from 'chalk'; -import * as portscanner from 'portscanner'; -import { getConnection } from 'typeorm'; - -import Logger from '@/services/logger'; -import loadConfig from '@/config/load'; -import { Config } from '@/config/types'; -import { lessThan } from '@/prelude/array'; -import { envOption } from '../env'; -import { showMachineInfo } from '@/misc/show-machine-info'; -import { initDb } from '../db/postgre'; - -//const _filename = fileURLToPath(import.meta.url); -const _filename = __filename; -const _dirname = dirname(_filename); - -const meta = JSON.parse(fs.readFileSync(`${_dirname}/../meta.json`, 'utf-8')); - -const logger = new Logger('core', 'cyan'); -const bootLogger = logger.createSubLogger('boot', 'magenta', false); - -function greet() { - if (!envOption.quiet) { - //#region Misskey logo - const v = `v${meta.version}`; - console.log(' _____ _ _ '); - console.log(' | |_|___ ___| |_ ___ _ _ '); - console.log(' | | | | |_ -|_ -| \'_| -_| | |'); - console.log(' |_|_|_|_|___|___|_,_|___|_ |'); - console.log(' ' + chalk.gray(v) + (' |___|\n'.substr(v.length))); - //#endregion - - console.log(' Misskey is an open-source decentralized microblogging platform.'); - console.log(chalk.keyword('orange')(' If you like Misskey, please donate to support development. https://www.patreon.com/syuilo')); - - console.log(''); - console.log(chalk`--- ${os.hostname()} {gray (PID: ${process.pid.toString()})} ---`); - } - - bootLogger.info('Welcome to Misskey!'); - bootLogger.info(`Misskey v${meta.version}`, null, true); -} - -function isRoot() { - // maybe process.getuid will be undefined under not POSIX environment (e.g. Windows) - return process.getuid != null && process.getuid() === 0; -} - -/** - * Init master process - */ -export async function masterMain() { - let config!: Config; - - // initialize app - try { - greet(); - showEnvironment(); - await showMachineInfo(bootLogger); - showNodejsVersion(); - config = loadConfigBoot(); - await connectDb(); - await validatePort(config); - } catch (e) { - bootLogger.error('Fatal error occurred during initialization', null, true); - process.exit(1); - } - - bootLogger.succ('Misskey initialized'); - - if (!envOption.disableClustering) { - await spawnWorkers(config.clusterLimit); - } - - bootLogger.succ(`Now listening on port ${config.port} on ${config.url}`, null, true); - - if (!envOption.noDaemons) { - require('../daemons/server-stats').default(); - require('../daemons/queue-stats').default(); - require('../daemons/janitor').default(); - } -} - -const runningNodejsVersion = process.version.slice(1).split('.').map(x => parseInt(x, 10)); -const requiredNodejsVersion = [11, 7, 0]; -const satisfyNodejsVersion = !lessThan(runningNodejsVersion, requiredNodejsVersion); - -function showEnvironment(): void { - const env = process.env.NODE_ENV; - const logger = bootLogger.createSubLogger('env'); - logger.info(typeof env === 'undefined' ? 'NODE_ENV is not set' : `NODE_ENV: ${env}`); - - if (env !== 'production') { - logger.warn('The environment is not in production mode.'); - logger.warn('DO NOT USE FOR PRODUCTION PURPOSE!', null, true); - } - - logger.info(`You ${isRoot() ? '' : 'do not '}have root privileges`); -} - -function showNodejsVersion(): void { - const nodejsLogger = bootLogger.createSubLogger('nodejs'); - - nodejsLogger.info(`Version ${runningNodejsVersion.join('.')}`); - - if (!satisfyNodejsVersion) { - nodejsLogger.error(`Node.js version is less than ${requiredNodejsVersion.join('.')}. Please upgrade it.`, null, true); - process.exit(1); - } -} - -function loadConfigBoot(): Config { - const configLogger = bootLogger.createSubLogger('config'); - let config; - - try { - config = loadConfig(); - } catch (exception) { - if (typeof exception === 'string') { - configLogger.error(exception); - process.exit(1); - } - if (exception.code === 'ENOENT') { - configLogger.error('Configuration file not found', null, true); - process.exit(1); - } - throw exception; - } - - configLogger.succ('Loaded'); - - return config; -} - -async function connectDb(): Promise<void> { - const dbLogger = bootLogger.createSubLogger('db'); - - // Try to connect to DB - try { - dbLogger.info('Connecting...'); - await initDb(); - const v = await getConnection().query('SHOW server_version').then(x => x[0].server_version); - dbLogger.succ(`Connected: v${v}`); - } catch (e) { - dbLogger.error('Cannot connect', null, true); - dbLogger.error(e); - process.exit(1); - } -} - -async function validatePort(config: Config): Promise<void> { - const isWellKnownPort = (port: number) => port < 1024; - - async function isPortAvailable(port: number): Promise<boolean> { - return await portscanner.checkPortStatus(port, '127.0.0.1') === 'closed'; - } - - if (config.port == null || Number.isNaN(config.port)) { - bootLogger.error('The port is not configured. Please configure port.', null, true); - process.exit(1); - } - - if (process.platform === 'linux' && isWellKnownPort(config.port) && !isRoot()) { - bootLogger.error('You need root privileges to listen on well-known port on Linux', null, true); - process.exit(1); - } - - if (!await isPortAvailable(config.port)) { - bootLogger.error(`Port ${config.port} is already in use`, null, true); - process.exit(1); - } -} - -async function spawnWorkers(limit: number = 1) { - const workers = Math.min(limit, os.cpus().length); - bootLogger.info(`Starting ${workers} worker${workers === 1 ? '' : 's'}...`); - await Promise.all([...Array(workers)].map(spawnWorker)); - bootLogger.succ('All workers started'); -} - -function spawnWorker(): Promise<void> { - return new Promise(res => { - const worker = cluster.fork(); - worker.on('message', message => { - if (message !== 'ready') return; - res(); - }); - }); -} diff --git a/src/boot/worker.ts b/src/boot/worker.ts deleted file mode 100644 index 362fa3f26b..0000000000 --- a/src/boot/worker.ts +++ /dev/null @@ -1,20 +0,0 @@ -import * as cluster from 'cluster'; -import { initDb } from '../db/postgre'; - -/** - * Init worker process - */ -export async function workerMain() { - await initDb(); - - // start server - await require('../server').default(); - - // start job queue - require('../queue').default(); - - if (cluster.isWorker) { - // Send a 'ready' message to parent process - process.send!('ready'); - } -} |