UNPKG

@shahadul-17/dispatcher

Version:

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

161 lines 8.02 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.DispatcherChildProcess = void 0; const logger_1 = require("@shahadul-17/logger"); const utilities_1 = require("@shahadul-17/utilities"); const process_1 = require("./process"); const service_provider_1 = require("@shahadul-17/service-provider"); const dispatcher_ipc_payload_flag_e_1 = require("./dispatcher-ipc-payload-flag.e"); class DispatcherChildProcess { constructor() { this.isDispatcherServiceInitializerInitialized = false; this.logger = new logger_1.Logger(DispatcherChildProcess); this.process = new process_1.Process(); this.serviceProvider = service_provider_1.ServiceProvider.getInstance(); // binding methods to current instance... this.initializeDispatcherServiceInitializerIfNotInitializedAsync = this.initializeDispatcherServiceInitializerIfNotInitializedAsync.bind(this); this.onRequestReceivedAsync = this.onRequestReceivedAsync.bind(this); this.startAsync = this.startAsync.bind(this); this.onEventOccurredAsync = this.onEventOccurredAsync.bind(this); this.onSpawnedAsync = this.onSpawnedAsync.bind(this); this.sendLogAsync = this.sendLogAsync.bind(this); this.sendAsync = this.sendAsync.bind(this); this.sendErrorAsync = this.sendErrorAsync.bind(this); } initializeDispatcherServiceInitializerIfNotInitializedAsync() { return __awaiter(this, void 0, void 0, function* () { // we won't re-initialize if already initialized... if (this.isDispatcherServiceInitializerInitialized) { return; } this.isDispatcherServiceInitializerInitialized = true; try { let serviceInitializerClass = require(this.process.options.commandLineArguments.serviceInitializerPath); const serviceInitializerClassName = utilities_1.StringUtilities.getDefaultIfUndefinedOrNullOrEmpty(this.process.options.commandLineArguments.serviceInitializerClassName, utilities_1.StringUtilities.getEmptyString(), true); if (!utilities_1.StringUtilities.isEmpty(serviceInitializerClassName)) { serviceInitializerClass = serviceInitializerClass[serviceInitializerClassName]; } const dispatcherServiceInitializer = new serviceInitializerClass(); yield dispatcherServiceInitializer.initializeAsync(this.process.processId, this.serviceProvider); } catch (error) { this.isDispatcherServiceInitializerInitialized = false; throw error; } }); } onRequestReceivedAsync(payload) { return __awaiter(this, void 0, void 0, function* () { if (payload.flag !== dispatcher_ipc_payload_flag_e_1.DispatcherIpcPayloadFlag.Dispatch) { return; } try { const service = this.serviceProvider.getByName(payload.serviceName, payload.serviceScopeName); const method = service[payload.methodName]; if (typeof method !== "function") { throw new Error(`Requested method, '${payload.methodName}' does not belong to the service, '${payload.serviceName}'.`); } const methodArguments = Array.isArray(payload.methodArguments) ? payload.methodArguments : []; let result = method.call(service, ...methodArguments); if (result instanceof Promise) { result = yield result; } yield this.sendAsync({ flag: dispatcher_ipc_payload_flag_e_1.DispatcherIpcPayloadFlag.Dispatch, payloadId: payload.payloadId, processId: this.process.processId, result: result, methodName: payload.methodName, serviceName: payload.serviceName, methodArguments: methodArguments, }); } catch (error) { yield this.sendErrorAsync(error, payload.payloadId); } }); } onSpawnedAsync(eventArguments) { return __awaiter(this, void 0, void 0, function* () { yield this.initializeDispatcherServiceInitializerIfNotInitializedAsync(); yield this.sendLogAsync(logger_1.LogLevel.Information, `Child process with ID '${this.process.processId}' has spawned.`); }); } onEventOccurredAsync(eventArguments) { return __awaiter(this, void 0, void 0, function* () { if (eventArguments.type === process_1.ProcessEventType.Spawn) { yield this.onSpawnedAsync(eventArguments); } else if (eventArguments.type === process_1.ProcessEventType.DataReceive) { if (!utilities_1.ObjectUtilities.isObject(eventArguments.data)) { return; } const payload = eventArguments.data; if (!utilities_1.NumberUtilities.isPositiveNumber(payload.flag)) { return; } yield this.onRequestReceivedAsync(payload); } }); } startAsync() { return __awaiter(this, void 0, void 0, function* () { this.process.addEventListener(process_1.ProcessEventType.Spawn, this.onEventOccurredAsync); this.process.addEventListener(process_1.ProcessEventType.DataReceive, this.onEventOccurredAsync); yield this.process.spawnAsync(); // global.console.log = this.sendLogAsync; }); } sendAsync(payload) { return __awaiter(this, void 0, void 0, function* () { let isSent = false; try { isSent = yield this.process.sendAsync(payload); } catch (error) { yield this.sendErrorAsync(error, payload.payloadId); } return isSent; }); } sendLogAsync(logLevel, ...parameters) { return this.sendAsync({ flag: dispatcher_ipc_payload_flag_e_1.DispatcherIpcPayloadFlag.Log, processId: this.process.processId, result: { logLevel, parameters, }, }); } sendErrorAsync(error, payloadId) { return __awaiter(this, void 0, void 0, function* () { const sanitizedError = utilities_1.ObjectUtilities.sanitize({ data: error, shallDeepSanitize: true, }); const payload = { flag: dispatcher_ipc_payload_flag_e_1.DispatcherIpcPayloadFlag.Error, processId: this.process.processId, result: sanitizedError, payloadId: payloadId, }; const isSent = yield this.sendAsync(payload); return isSent; }); } } exports.DispatcherChildProcess = DispatcherChildProcess; const dispatcherChildProcess = new DispatcherChildProcess(); dispatcherChildProcess.startAsync(); // we shall keep waiting to make sure that this child process does not exit... utilities_1.ThreadUtilities.waitAsync(); //# sourceMappingURL=dispatcher-child-process.js.map