| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- "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 });
- const child_process_1 = require("child_process");
- const RpcIpcMessagePortClosedError_1 = require("./error/RpcIpcMessagePortClosedError");
- function createRpcIpcMessagePort(process) {
- const messageListeners = new Set();
- const errorListeners = new Set();
- let closedError;
- const handleExit = (code, signal) => __awaiter(this, void 0, void 0, function* () {
- closedError = new RpcIpcMessagePortClosedError_1.RpcIpcMessagePortClosedError(code
- ? `Process ${process.pid} exited with code "${code}" [${signal}]`
- : `Process ${process.pid} exited [${signal}].`, code, signal);
- errorListeners.forEach((listener) => {
- if (closedError) {
- listener(closedError);
- }
- });
- yield port.close();
- });
- const handleMessage = (message) => {
- messageListeners.forEach((listener) => {
- listener(message);
- });
- };
- process.on('message', handleMessage);
- process.on('exit', handleExit);
- const port = {
- dispatchMessage: (message) => __awaiter(this, void 0, void 0, function* () {
- return new Promise((resolve, reject) => {
- if (!process.connected) {
- reject(closedError ||
- new RpcIpcMessagePortClosedError_1.RpcIpcMessagePortClosedError(`Process ${process.pid} doesn't have open IPC channels`));
- }
- if (process.send) {
- process.send(Object.assign(Object.assign({}, message), { source: process.pid }), undefined, undefined, (sendError) => {
- if (sendError) {
- if (!closedError) {
- closedError = new RpcIpcMessagePortClosedError_1.RpcIpcMessagePortClosedError(`Cannot send the message - the message port has been closed for the process ${process.pid}.`);
- }
- reject(closedError);
- }
- else {
- resolve();
- }
- });
- }
- else {
- reject(new RpcIpcMessagePortClosedError_1.RpcIpcMessagePortClosedError(`Process ${process.pid} doesn't have IPC channels`));
- }
- });
- }),
- addMessageListener: (listener) => {
- messageListeners.add(listener);
- },
- removeMessageListener: (listener) => {
- messageListeners.delete(listener);
- },
- addErrorListener: (listener) => {
- errorListeners.add(listener);
- },
- removeErrorListener: (listener) => {
- errorListeners.delete(listener);
- },
- isOpen: () => !!process.connected,
- open: () => __awaiter(this, void 0, void 0, function* () {
- if (!process.connected || closedError) {
- throw (closedError ||
- new RpcIpcMessagePortClosedError_1.RpcIpcMessagePortClosedError(`Cannot open closed IPC channel for process ${process.pid}.`));
- }
- }),
- close: () => __awaiter(this, void 0, void 0, function* () {
- process.off('message', handleMessage);
- process.off('exit', handleExit);
- messageListeners.clear();
- errorListeners.clear();
- if (process.disconnect && process.connected) {
- process.disconnect();
- }
- }),
- };
- return port;
- }
- exports.createRpcIpcMessagePort = createRpcIpcMessagePort;
- function createRpcIpcForkedProcessMessagePort(filePath, memoryLimit = 2048, autoRecreate = true) {
- function createChildProcess() {
- return child_process_1.fork(filePath, [], {
- execArgv: [`--max-old-space-size=${memoryLimit}`],
- stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
- });
- }
- const messageListeners = new Set();
- const errorListeners = new Set();
- let childProcess = createChildProcess();
- let port = createRpcIpcMessagePort(childProcess);
- return {
- dispatchMessage: (message) => port.dispatchMessage(message),
- addMessageListener: (listener) => {
- messageListeners.add(listener);
- return port.addMessageListener(listener);
- },
- removeMessageListener: (listener) => {
- messageListeners.delete(listener);
- return port.removeMessageListener(listener);
- },
- addErrorListener: (listener) => {
- errorListeners.add(listener);
- return port.addErrorListener(listener);
- },
- removeErrorListener: (listener) => {
- errorListeners.delete(listener);
- return port.removeErrorListener(listener);
- },
- isOpen: () => port.isOpen(),
- open: () => __awaiter(this, void 0, void 0, function* () {
- if (!port.isOpen() && autoRecreate) {
- // recreate the process and add existing message listeners
- childProcess = createChildProcess();
- port = createRpcIpcMessagePort(childProcess);
- messageListeners.forEach((listener) => {
- port.addMessageListener(listener);
- });
- errorListeners.forEach((listener) => {
- port.addErrorListener(listener);
- });
- }
- else {
- return port.open();
- }
- }),
- close: () => __awaiter(this, void 0, void 0, function* () {
- yield port.close();
- messageListeners.clear();
- errorListeners.clear();
- if (childProcess) {
- childProcess.kill('SIGTERM');
- childProcess = undefined;
- }
- }),
- };
- }
- exports.createRpcIpcForkedProcessMessagePort = createRpcIpcForkedProcessMessagePort;
|