UNPKG

pipeproc

Version:

Multi-process log processing for nodejs

125 lines (124 loc) 4.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const net_1 = require("net"); const tls_1 = require("tls"); const debug_1 = __importDefault(require("debug")); const uuid_1 = require("uuid"); const fs_1 = require("fs"); const xpipe_1 = require("./xpipe"); const send_1 = require("./send"); const d = debug_1.default("pipeproc:socket:bind"); function bind(address, options, callback) { //tslint:disable no-any const messageListeners = []; //tslint:enable no-any const socketMap = new Map(); const server = options.tls ? tls_1.createServer({ ca: options.tls.ca, key: options.tls.key, cert: options.tls.cert, requestCert: true, rejectUnauthorized: true }, connectionHandler) : net_1.createServer(connectionHandler); function connectionHandler(socket) { d("new connection", socket.address()); const binder = createBinder(socket); socketMap.set(socket, binder); socket.setEncoding("utf8"); socket.setNoDelay(true); socket.on("end", function () { socketMap.delete(socket); }); socket.on("close", function () { socketMap.delete(socket); }); socket.on("error", function (err) { d(err); }); socket.on("data", function (chunk) { const data = binder.buffer + chunk; const messages = data.split("%EOM%"); binder.buffer = messages.pop() || ""; messages.forEach(function (msg) { let parsedData; try { parsedData = JSON.parse(msg); } catch (e) { d("Socket data parsing error:", e, msg); return; } messageListeners.forEach(function (listener) { listener(parsedData, binder); }); }); }); } const socketServer = { close: function () { if (address.includes("ipc://")) { const socketPath = address.replace("ipc://", ""); try { fs_1.unlinkSync(socketPath); } catch (_e) { } } server.close(); d("message socket closed"); }, onMessage: function (listener) { messageListeners.push(listener); } }; let connectionRetries = 0; let cbCalled = false; server.on("error", function (err) { if (err.code === "EADDRINUSE" && address.includes("ipc://") && connectionRetries < 3) { const socketPath = address.replace("ipc://", ""); try { fs_1.unlinkSync(socketPath); setTimeout(function () { connectionRetries += 1; startServer(server, address); }, 100); } catch (_e) { } } else { d("Socket error:", err); if (!cbCalled) { cbCalled = true; callback(err); } } }); server.once("listening", function () { d("Socket server is listening on", address); if (!cbCalled) { cbCalled = true; callback(null, socketServer); } }); startServer(server, address); } exports.bind = bind; function startServer(server, address) { if (address.includes("ipc://")) { const socketPath = address.replace("ipc://", ""); server.listen(xpipe_1.xpipe(socketPath)); } else if (address.includes("tcp://")) { const parts = address.replace("tcp://", "").split(":"); server.listen(parseInt(parts[1]), parts[0]); } } function createBinder(socket) { return { id: uuid_1.v4(), send: send_1.getSender(socket), buffer: "" }; }