@shahadul-17/dispatcher
Version:
Defines a mechanism for parallel processing and CPU intensive tasks in Node.js
161 lines • 8.02 kB
JavaScript
"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