UNPKG

advanced-console-log

Version:

Advanced Console Log (ACL), available as the `advanced-console-log` NPM package, is a lightweight logging module for Node.js applications. It supports console and file logging with various levels, colors, and additional features such as memory usage track

124 lines (107 loc) 3.81 kB
const path = require("path"); const { EventEmitter } = require("events"); /** * Class responsible for managing worker thread communication and handling log messages. */ class WorkerHandler extends EventEmitter { /** * Initializes a new instance of WorkerHandler. * @param {Object} config - Configuration options for the worker handler. * @param {string} [config.workerScriptPath] - Optional path to the worker script. * @param {string} config.outputFilename - Log file name for output. * @param {number} [config.maxLogFileSizeMB=10] - Maximum size of the log file in MB. * @param {number} [config.maxLogFiles=5] - Maximum number of rotated log files to keep. * @param {boolean} [config.includeTimestamps=true] - Whether to include timestamps in log messages. */ constructor(config) { super(); this.config = { ...config }; this.workerScriptPath = this.config.workerScriptPath || path.join(__dirname, "../workers/logWorker.js"); this.worker = null; this.pendingMessages = 0; this.isClosed = false; // Properly set to true only after shutdown is complete this.closeSignalSent = false; // Track if a close signal was already sent this.debug = false; } /** * Initializes the worker thread and sets up event listeners for the worker. */ _initializeWorker() { const { Worker, isMainThread } = require("worker_threads"); if (isMainThread) { this.worker = new Worker(this.workerScriptPath, { workerData: this.config, }); this.worker.on("message", (msg) => this.handleWorkerMessage(msg)); if (this.debug) { this.worker.on("error", (err) => console.error(`Worker Error: ${err.message}`) ); this.worker.on("exit", (code) => console.log(`Worker exited with code ${code}`) ); } } } /** * Handles incoming messages from the worker thread. * @param {string} msg - The message received from the worker. */ handleWorkerMessage(msg) { if (msg === "processed") { this.pendingMessages--; if (this.pendingMessages === 0 && this.closeSignalSent) { this.emit("drain"); } } else if (msg === "closed") { this.isClosed = true; // Update the flag when shutdown is acknowledged this.emit("closed"); } } /** * Sends a log message to the worker thread. * @param {string} message - The log message to be sent to the worker. */ logToWorker(message) { if (this.worker) { this.pendingMessages++; this.worker.postMessage(message); } } /** * Initiates the close process for the worker, ensuring all messages are processed and the worker is terminated. * @returns {Promise<void>} - Resolves when the worker has been successfully closed. */ async closeWorker() { this.closeSignalSent = true; // Indicate that the close signal is being handled // Wait for pending messages to be processed await this.waitForPendingMessages(); if (this.worker) { this.isClosed = false; // Reset isClosed until worker responds this.worker.postMessage("close"); // Wait for the worker to acknowledge closure await this.waitForWorkerClosure(); await this.worker.terminate(); this.worker = null; } } /** * Waits for all pending messages to be processed before continuing. * @returns {Promise<void>} - Resolves when there are no more pending messages. */ waitForPendingMessages() { if (this.pendingMessages === 0) return Promise.resolve(); return new Promise((resolve) => this.once("drain", resolve)); } /** * Waits for the worker to acknowledge its shutdown before proceeding. * @returns {Promise<void>} - Resolves when the worker has acknowledged the "closed" signal. */ waitForWorkerClosure() { if (this.isClosed) return Promise.resolve(); return new Promise((resolve) => this.once("closed", resolve)); } } module.exports = WorkerHandler;