UNPKG

@shahadul-17/dispatcher

Version:

Defines a mechanism for parallel processing and CPU intensive tasks in Node.js

102 lines 4.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParentProcess = void 0; const utilities_1 = require("@shahadul-17/utilities"); const event_manager_1 = require("@shahadul-17/event-manager"); const process_event_type_e_1 = require("./process-event-type.e"); const END_OF_DATA_MARKER = "<--- END OF DATA --->"; /** * Child processes shall use this class to communicate with the parent process. */ class ParentProcess extends event_manager_1.EventManager { constructor(options) { super(); this._taskCount = 0; this._options = options; this._options.commandLineArguments = utilities_1.ArgumentsParser.toObject(); this._options.processId = parseInt(this._options.commandLineArguments.processId); this.streamReader = new utilities_1.StreamReader(); this.streamReader.setLineDelimiter(END_OF_DATA_MARKER); // binding methods... this.incrementTaskCount = this.incrementTaskCount.bind(this); this.decrementTaskCount = this.decrementTaskCount.bind(this); this.onDataReceivedAsync = this.onDataReceivedAsync.bind(this); this.spawnAsync = this.spawnAsync.bind(this); this.sendAsync = this.sendAsync.bind(this); } get isChildProcess() { return true; } get taskCount() { return this._taskCount; } get processId() { return this.options.processId; } get options() { return this._options; } incrementTaskCount(step) { // if the provided step is not a positive number... if (!utilities_1.NumberUtilities.isPositiveNumber(step)) { // we shall set the step to 1... step = 1; } this._taskCount = this._taskCount + step; return this._taskCount; } decrementTaskCount(step) { // if the provided step is not a positive number... if (!utilities_1.NumberUtilities.isPositiveNumber(step)) { // we shall set the step to 1... step = 1; } this._taskCount = this._taskCount - step; // task count can never be less than zero... if (this._taskCount < 0) { this._taskCount = 0; } return this._taskCount; } onDataReceivedAsync(chunk) { return __awaiter(this, void 0, void 0, function* () { this.streamReader.append(chunk); let data; while (utilities_1.ObjectUtilities.isObject(data = this.streamReader.readObject())) { // dispatches data receive event... this.dispatchEventListeners({ type: process_event_type_e_1.ProcessEventType.DataReceive, data: data, }); } }); } spawnAsync() { return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { process.stdin.setEncoding("utf-8"); process.stdin.on("data", chunk => this.onDataReceivedAsync(chunk)); this.dispatchEventListeners({ type: process_event_type_e_1.ProcessEventType.Spawn, processId: this.processId, }); resolve(this); })); } sendAsync(data) { return __awaiter(this, void 0, void 0, function* () { // any error thrown by this method shall be sent to the parent... let dataAsJson = utilities_1.JsonSerializer.serialize(data, { shallDeepSanitize: true, }); dataAsJson = `${dataAsJson}${END_OF_DATA_MARKER}\n`; // <-- we must add the new-line character... // we shall send data to the parent process... process.stdout.cork(); const isSent = process.stdout.write(dataAsJson, "utf-8"); process.stdout.uncork(); return isSent; }); } } exports.ParentProcess = ParentProcess; //# sourceMappingURL=parent-process.js.map