Add ability to run server cluster
This commit is contained in:
parent
0633734156
commit
17adb818be
@ -8,6 +8,8 @@ export interface Bootstrap {
|
||||
readonly database: TypeORMDatabase
|
||||
getConfig(): Config
|
||||
listen(port?: number | string, hostname?: string): Promise<void>
|
||||
startCluster(
|
||||
workers: number, port?: number | string, hostname?: string): Promise<void>
|
||||
getAddress(): AddressInfo | string
|
||||
close(): Promise<void>
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { TypeORMDatabase, TypeORMLogger } from '@rondo.dev/db-typeorm'
|
||||
import assert from 'assert'
|
||||
import { createNamespace, Namespace } from 'cls-hooked'
|
||||
import cluster from 'cluster'
|
||||
import { Server } from 'http'
|
||||
import { AddressInfo } from 'net'
|
||||
import { loggerFactory } from '../logger'
|
||||
@ -8,7 +10,7 @@ import { Bootstrap } from './Bootstrap'
|
||||
import { Config } from './Config'
|
||||
import { ServerConfigurator } from './configureServer'
|
||||
import { createServer } from './createServer'
|
||||
import { TypeORMDatabase, TypeORMLogger } from '@rondo.dev/db-typeorm'
|
||||
|
||||
|
||||
export interface ServerBootstrapParams {
|
||||
readonly config: Config
|
||||
@ -79,7 +81,7 @@ export class ServerBootstrap implements Bootstrap {
|
||||
|
||||
async listen(
|
||||
port: number | string | undefined = process.env.PORT || 3000,
|
||||
hostname: string | undefined= process.env.BIND_HOST,
|
||||
hostname: string | undefined = process.env.BIND_HOST,
|
||||
) {
|
||||
const apiLogger = loggerFactory.getLogger('api')
|
||||
try {
|
||||
@ -91,6 +93,36 @@ export class ServerBootstrap implements Bootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
async startCluster(
|
||||
workers: number,
|
||||
port?: number | string,
|
||||
hostname?: string,
|
||||
) {
|
||||
const apiLogger = loggerFactory.getLogger('api')
|
||||
|
||||
if (cluster.isMaster) {
|
||||
apiLogger.info('Started master process %d, starting %d workers...',
|
||||
process.pid, workers)
|
||||
|
||||
// Fork workers.
|
||||
for (let i = 0; i < workers; i++) {
|
||||
cluster.fork({
|
||||
WORKER_ID: i + 1,
|
||||
})
|
||||
}
|
||||
|
||||
cluster.on('exit', (worker, code, signal) => {
|
||||
console.log(`worker ${worker.process.pid} died`)
|
||||
})
|
||||
} else {
|
||||
await this.listen(port, hostname)
|
||||
apiLogger.info(
|
||||
'Started worker %d (worker id %s)', process.pid, process.env.WORKER_ID)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected async start(
|
||||
port: number | string | undefined = process.env.PORT,
|
||||
hostname?: string,
|
||||
|
||||
@ -1,8 +1,28 @@
|
||||
import { Bootstrap } from "../application";
|
||||
import { argparse, arg } from "@rondo.dev/argparse";
|
||||
import { arg, argparse } from '@rondo.dev/argparse'
|
||||
import { cpus } from 'os'
|
||||
import { Bootstrap } from '../application'
|
||||
|
||||
const numberOfCPUs = cpus().length
|
||||
|
||||
const startArgs = {
|
||||
host: arg('string', {
|
||||
description: '',
|
||||
}),
|
||||
socket: arg('number', {
|
||||
alias: 's',
|
||||
description: 'Socket to listen on',
|
||||
}),
|
||||
port: arg('number', {
|
||||
default: 3000,
|
||||
alias: 'p',
|
||||
description: 'Port to listen on',
|
||||
}),
|
||||
help: arg('boolean', {alias: 'h'}),
|
||||
}
|
||||
|
||||
export function run(bootstrap: Bootstrap, argv: string[]) {
|
||||
const choices: Array<keyof typeof commands> = ['start', 'migrate']
|
||||
const choices: Array<keyof typeof commands> = Object
|
||||
.keys(commands) as Array<keyof typeof commands>
|
||||
const {parse} = argparse({
|
||||
command: arg('string', {
|
||||
default: 'start',
|
||||
@ -24,24 +44,23 @@ export function run(bootstrap: Bootstrap, argv: string[]) {
|
||||
|
||||
const commands = {
|
||||
async start(bootstrap: Bootstrap, argv: string[]) {
|
||||
const {parse} = argparse({
|
||||
host: arg('string', {
|
||||
description: '',
|
||||
}),
|
||||
socket: arg('number', {
|
||||
alias: 's',
|
||||
description: 'Socket to listen on',
|
||||
}),
|
||||
port: arg('number', {
|
||||
default: 3000,
|
||||
alias: 'p',
|
||||
description: 'Port to listen on',
|
||||
}),
|
||||
help: arg('boolean', {alias: 'h'}),
|
||||
})
|
||||
const {parse} = argparse(startArgs, 'Start the server')
|
||||
const args = parse(argv)
|
||||
await bootstrap.listen(args.port || args.socket, args.host)
|
||||
},
|
||||
async cluster(bootstrap: Bootstrap, argv: string[]) {
|
||||
const {parse} = argparse({
|
||||
...startArgs,
|
||||
workers: arg('number', {
|
||||
alias: 'w',
|
||||
description: 'Number of workers to start',
|
||||
default: numberOfCPUs,
|
||||
}),
|
||||
}, 'Start in cluster')
|
||||
const args = parse(argv)
|
||||
await bootstrap
|
||||
.startCluster(args.workers, args.port || args.socket, args.host)
|
||||
},
|
||||
async migrate(bootstrap: Bootstrap, argv: string[]) {
|
||||
const {parse} = argparse({
|
||||
undo: arg('boolean', {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user