Compare commits
2 Commits
a37fd81052
...
68512ec871
Author | SHA1 | Date | |
---|---|---|---|
68512ec871 | |||
268c3421dd |
@ -94,12 +94,7 @@ class Controller extends EventEmitter {
|
|||||||
const {
|
const {
|
||||||
projectName,
|
projectName,
|
||||||
shardCount = 1,
|
shardCount = 1,
|
||||||
shardOptions = {},
|
|
||||||
serverOptions = {} as ServerOptions,
|
serverOptions = {} as ServerOptions,
|
||||||
logger = {},
|
|
||||||
discord = {},
|
|
||||||
databases = {},
|
|
||||||
rabbitConfig = {} as BrokerOptions
|
|
||||||
} = this.#_options;
|
} = this.#_options;
|
||||||
this.#_logger.info(`Spawning ${shardCount} shards`);
|
this.#_logger.info(`Spawning ${shardCount} shards`);
|
||||||
|
|
||||||
@ -124,22 +119,12 @@ class Controller extends EventEmitter {
|
|||||||
process.stdin.on('data', (data) => {
|
process.stdin.on('data', (data) => {
|
||||||
const raw = data.toString('utf-8');
|
const raw = data.toString('utf-8');
|
||||||
const words = raw.split(' ').map(word => word.trim());
|
const words = raw.split(' ').map(word => word.trim());
|
||||||
this._handleStdin(words);
|
this.#handleStdin(words);
|
||||||
});
|
});
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (let i = 0; i < shardCount; i++) {
|
for (let i = 0; i < shardCount; i++) {
|
||||||
const shard = new Shard(this, i, {
|
const shard = this.createShard();
|
||||||
serverOptions: {
|
|
||||||
...serverOptions, logger, discord, databases, rabbitConfig
|
|
||||||
},
|
|
||||||
...shardOptions,
|
|
||||||
env: this.#_options.env,
|
|
||||||
path: this.#_serverFilePath
|
|
||||||
});
|
|
||||||
this.#_logger.attach(shard);
|
|
||||||
this._setListeners(shard);
|
|
||||||
this.#_shards.set(i, shard);
|
|
||||||
promises.push(shard.spawn());
|
promises.push(shard.spawn());
|
||||||
|
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
@ -150,16 +135,47 @@ class Controller extends EventEmitter {
|
|||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
this.emit('built');
|
this.emit('built');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleMessage (shard: Shard, msg: IPCMessage) {
|
createShard () {
|
||||||
|
|
||||||
|
const ids = this.shards.map(s => s.id);
|
||||||
|
const id = ids.length ? Math.max(...ids) + 1 : 0;
|
||||||
|
const shard = new Shard(this, id, this.shardOptions);
|
||||||
|
this.shards.set(shard.id, shard);
|
||||||
|
this.#_logger.attach(shard);
|
||||||
|
this.#setListeners(shard);
|
||||||
|
return shard;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get shardOptions () {
|
||||||
|
const {
|
||||||
|
shardOptions = {},
|
||||||
|
serverOptions = {} as ServerOptions,
|
||||||
|
logger = {},
|
||||||
|
discord = {},
|
||||||
|
databases = {},
|
||||||
|
rabbitConfig = {} as BrokerOptions
|
||||||
|
} = this.#_options;
|
||||||
|
return {
|
||||||
|
serverOptions: {
|
||||||
|
...serverOptions, logger, discord, databases, rabbitConfig
|
||||||
|
},
|
||||||
|
...shardOptions,
|
||||||
|
env: this.#_options.env,
|
||||||
|
path: this.#_serverFilePath
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#handleMessage (shard: Shard, msg: IPCMessage) {
|
||||||
if (msg._logger)
|
if (msg._logger)
|
||||||
return;
|
return;
|
||||||
this.#_logger.debug(`Message from ${shard.id}: ${inspect(msg)}`);
|
this.#_logger.debug(`Message from ${shard.id}: ${inspect(msg)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setListeners (shard: Shard) {
|
#setListeners (shard: Shard) {
|
||||||
shard.on('death', () => this.#_logger.info(`Shard ${shard.id} has died`));
|
shard.on('death', () => this.#_logger.info(`Shard ${shard.id} has died`));
|
||||||
shard.on('fatal', ({ message }) => this.#_logger.warn(`Shard ${shard.id} has died fatally: ${message}`));
|
shard.on('fatal', ({ message }) => this.#_logger.warn(`Shard ${shard.id} has died fatally: ${message}`));
|
||||||
shard.on('shutdown', () => this.#_logger.info(`Shard ${shard.id} is shutting down gracefully`));
|
shard.on('shutdown', () => this.#_logger.info(`Shard ${shard.id} is shutting down gracefully`));
|
||||||
@ -169,10 +185,10 @@ class Controller extends EventEmitter {
|
|||||||
shard.on('error', (err) => this.#_logger.error(`Shard ${shard.id} ran into an error:\n${err.stack}`));
|
shard.on('error', (err) => this.#_logger.error(`Shard ${shard.id} ran into an error:\n${err.stack}`));
|
||||||
shard.on('warn', (msg) => this.#_logger.warn(`Warning from shard ${shard.id}: ${msg}`, { broadcast: true }));
|
shard.on('warn', (msg) => this.#_logger.warn(`Warning from shard ${shard.id}: ${msg}`, { broadcast: true }));
|
||||||
|
|
||||||
shard.on('message', (msg) => this._handleMessage(shard, msg));
|
shard.on('message', (msg) => this.#handleMessage(shard, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _handleStdin (words: string[]) {
|
async #handleStdin (words: string[]) {
|
||||||
|
|
||||||
words = words.filter(word => word.length);
|
words = words.filter(word => word.length);
|
||||||
if (!words.length)
|
if (!words.length)
|
||||||
@ -195,7 +211,8 @@ class Controller extends EventEmitter {
|
|||||||
|
|
||||||
if (rest.args.help) {
|
if (rest.args.help) {
|
||||||
if (command.help)
|
if (command.help)
|
||||||
return command.help;
|
// eslint-disable-next-line no-console
|
||||||
|
return console.log(command.help);
|
||||||
return this.#_logger.info(`Help for ${command.name} unavailable at this time`);
|
return this.#_logger.info(`Help for ${command.name} unavailable at this time`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import BaseCommand from "../BaseCommand.js";
|
import BaseCommand from "../BaseCommand.js";
|
||||||
import Controller from "../Controller.js";
|
import Controller from "../Controller.js";
|
||||||
import { OptionType } from '@navy.gif/commandparser';
|
import { ArgsResult, OptionType } from '@navy.gif/commandparser';
|
||||||
|
|
||||||
class StartCommand extends BaseCommand {
|
class StartCommand extends BaseCommand {
|
||||||
|
|
||||||
@ -12,12 +12,44 @@ class StartCommand extends BaseCommand {
|
|||||||
aliases: [ 's' ],
|
aliases: [ 's' ],
|
||||||
flag: true,
|
flag: true,
|
||||||
type: OptionType.INTEGER
|
type: OptionType.INTEGER
|
||||||
|
}, {
|
||||||
|
name: 'amount',
|
||||||
|
type: OptionType.INTEGER
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
execute (_message: unknown, _args?: unknown): Promise<unknown> {
|
async execute ({ args }: { subcommand: string, args: ArgsResult }): Promise<string> {
|
||||||
throw new Error("Method not implemented.");
|
const { shard, amount } = args;
|
||||||
|
const { shards } = this.controller;
|
||||||
|
|
||||||
|
const n = amount?.value as number || 0;
|
||||||
|
let id = -1;
|
||||||
|
|
||||||
|
if (shard)
|
||||||
|
id = shard.value as number;
|
||||||
|
|
||||||
|
let out = '';
|
||||||
|
if (id >= 0) {
|
||||||
|
const s = shards.get(id);
|
||||||
|
if (!s)
|
||||||
|
return `Shard ${id} doesn't exist`;
|
||||||
|
if (s.ready)
|
||||||
|
return `Shard ${id} is already running`;
|
||||||
|
await s.spawn();
|
||||||
|
out += `Started shard ${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > 0) {
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
const s = this.controller.createShard();
|
||||||
|
await s.spawn(true);
|
||||||
|
}
|
||||||
|
out += `\nSpawned ${n} shards`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,53 @@
|
|||||||
|
import { ArgsResult, OptionType } from "@navy.gif/commandparser";
|
||||||
import BaseCommand from "../BaseCommand.js";
|
import BaseCommand from "../BaseCommand.js";
|
||||||
import Controller from "../Controller.js";
|
import Controller from "../Controller.js";
|
||||||
|
|
||||||
class StopCommand extends BaseCommand {
|
class StopCommand extends BaseCommand {
|
||||||
constructor (controller: Controller) {
|
constructor (controller: Controller) {
|
||||||
super(controller, {
|
super(controller, {
|
||||||
name: 'stop'
|
name: 'stop',
|
||||||
|
options: [{
|
||||||
|
name: 'shard',
|
||||||
|
type: OptionType.INTEGER,
|
||||||
|
flag: true,
|
||||||
|
}, {
|
||||||
|
name: 'all',
|
||||||
|
flag: true,
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
valueOptional: true,
|
||||||
|
defaultValue: true
|
||||||
|
}, {
|
||||||
|
name: 'prune',
|
||||||
|
flag: true,
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
valueOptional: true,
|
||||||
|
defaultValue: true
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute (_message: unknown, _args?: unknown) {
|
async execute ({ args }: { subcommand: string, args: ArgsResult }) {
|
||||||
//
|
const id = args.shard?.value;
|
||||||
|
const all = args.all?.value || false;
|
||||||
|
const prune = args.prune?.value || false;
|
||||||
|
if (typeof id !== 'number' && !all)
|
||||||
|
return `Must supply either --all or --shard option`;
|
||||||
|
|
||||||
|
const { shards } = this.controller;
|
||||||
|
const targets = all ? shards : shards.filter(shard => shard.id === id);
|
||||||
|
const ids = targets.map(s => s.id);
|
||||||
|
|
||||||
|
for (const shard of targets.values()) {
|
||||||
|
await shard.kill();
|
||||||
|
if (prune)
|
||||||
|
shards.delete(shard.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = `Stopped ${all ? `all shards (${ids.join(', ')})` : `shard ${id}`}.`;
|
||||||
|
if (prune)
|
||||||
|
out += ' Pruned stopped shards';
|
||||||
|
return out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user