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.

133 lines (132 loc) 4.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkerClient = exports.Worker = void 0; const worker_threads_1 = require("worker_threads"); const listen_1 = require("./listen"); class Worker { file; /** The worker process. */ process = null; /** The options for the worker process. */ workerOptions; /** Type-safe listener manager */ _listeners = new listen_1.ListenerManager(); /** Creates an instance of Worker. */ constructor(file, options) { this.file = file; this.workerOptions = { workerData: options.clusterData, ...options, }; } /** Spawns the worker. */ spawn() { if (this.process && this.process.threadId) return this.process; this.process = new worker_threads_1.Worker(this.file, this.workerOptions); return this.process; } /** Respawns the worker. */ async respawn() { await this.kill(); return this.spawn(); } /** Kills the worker with proper cleanup. */ async kill() { if (!this.process || !this.process.threadId) { this._cleanup(); return false; } try { const forceTerminateTimer = setTimeout(() => { if (this.process && this.process.threadId) { console.warn('Force terminating worker thread.'); this.process.terminate(); } }, 5000); return new Promise((resolve) => { if (!this.process || !this.process.threadId) { clearTimeout(forceTerminateTimer); this._cleanup(); resolve(false); return; } const cleanup = () => { clearTimeout(forceTerminateTimer); this._cleanup(); }; const onExit = () => { cleanup(); resolve(true); }; const onError = (err) => { console.error('Error during worker termination:', err); cleanup(); resolve(false); }; this.process.removeAllListeners('exit'); this.process.removeAllListeners('error'); this.process.once('exit', onExit); this.process.once('error', onError); this.process.terminate(); }); } catch (error) { console.error('Worker termination failed:', error); this._cleanup(); return false; } } /** Clean up worker and listeners */ _cleanup() { if (this.process) this.process.removeAllListeners(); this._listeners.clear(); this.process = null; } /** Sends a message to the worker. */ send(message) { return new Promise((resolve, reject) => { if (!this.process || !this.process.threadId) { reject(new Error('No active worker to send message to')); return; } try { this.process.postMessage(message); resolve(); } catch (error) { console.error('Data sending failed:', message); reject(error); } }); } } exports.Worker = Worker; /** Worker client class. */ class WorkerClient { /** The IPC port of the worker. */ ipc; /** Creates an instance of WorkerClient. */ constructor() { this.ipc = worker_threads_1.parentPort; } /** Sends a message to the worker. */ send(message) { return new Promise((resolve, reject) => { if (!this.ipc) { reject(new Error('No IPC port available')); return; } try { this.ipc.postMessage(message); resolve(); } catch (error) { console.error('Data sending failed:', message); reject(error); } }); } } exports.WorkerClient = WorkerClient;