UNPKG

status-sharding

Version:

Welcome to Status Sharding! This package is designed to provide an efficient and flexible solution for sharding Discord bots, allowing you to scale your bot across multiple processes or workers.

138 lines (137 loc) 4.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChildClient = exports.Child = void 0; const listen_1 = require("./listen"); const child_process_1 = require("child_process"); class Child { file; /** The child process. */ process = null; /** The options for the child process. */ processOptions = {}; /** Type-safe listener manager */ _listeners = new listen_1.ListenerManager(); /** Creates an instance of Child. */ constructor(file, options) { this.file = file; this.processOptions = { cwd: options.cwd, detached: options.detached, execArgv: options.execArgv, env: options.clusterData || options.env, execPath: options.execPath, gid: options.gid, serialization: options.serialization, signal: options.signal, killSignal: options.killSignal, silent: options.silent, stdio: options.stdio, uid: options.uid, windowsVerbatimArguments: options.windowsVerbatimArguments, timeout: options.timeout, args: options.args, }; } /** Spawns the child process. */ spawn() { if (this.process && !this.process.killed) return this.process; this.process = (0, child_process_1.fork)(this.file, this.processOptions.args, this.processOptions); return this.process; } /** Respawns the child process. */ async respawn() { await this.kill(); return this.spawn(); } /** Kills the child process with proper cleanup. */ async kill() { if (!this.process || this.process.killed) { this._cleanup(); return false; } try { const forceKillTimer = setTimeout(() => { if (this.process && !this.process.killed) { console.warn('Force killing process with SIGKILL.'); this.process.kill('SIGKILL'); } }, 5000); return new Promise((resolve) => { if (!this.process || this.process.killed) { clearTimeout(forceKillTimer); this._cleanup(); resolve(false); return; } const cleanup = () => { clearTimeout(forceKillTimer); this._cleanup(); }; const onExit = () => { cleanup(); resolve(true); }; const onError = (err) => { console.error('Error during child process kill:', err); cleanup(); resolve(false); }; this.process.removeAllListeners('exit'); this.process.removeAllListeners('error'); this.process.once('exit', onExit); this.process.once('error', onError); this.process.kill('SIGTERM'); }); } catch (error) { console.error('Child termination failed:', error); this._cleanup(); return false; } } /** Clean up process and listeners */ _cleanup() { if (this.process) this.process.removeAllListeners(); this._listeners.clear(); this.process = null; } /** Sends a message to the child process. */ send(message) { return new Promise((resolve, reject) => { if (!this.process || this.process.killed) { reject(new Error('No active process to send message to')); return; } this.process.send(message, (err) => { if (err) reject(err); else resolve(); }); }); } } exports.Child = Child; /** Child client class. */ class ChildClient { /** The IPC process. */ ipc; /** Creates an instance of ChildClient. */ constructor() { this.ipc = process; } /** Sends a message to the child process. */ send(message) { return new Promise((resolve, reject) => { this.ipc.send?.(message, (err) => { if (err) reject(err); else resolve(); }); }); } } exports.ChildClient = ChildClient;