UNPKG

reliable-zeromq

Version:

A collection of reliable zeromq messaging constructs

193 lines 13.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ZMQRequest = exports.ERequestResponse = exports.ERequestBody = void 0; const typescript_collections_1 = require("typescript-collections"); const uniqid_1 = __importDefault(require("uniqid")); const zmq = __importStar(require("zeromq")); const Config_1 = __importDefault(require("./Config")); const Errors_1 = require("./Errors"); const Delay_1 = require("./Utils/Delay"); const ZMQResponse_1 = require("./ZMQResponse"); var ERequestBody; (function (ERequestBody) { ERequestBody[ERequestBody["RequesterId"] = 0] = "RequesterId"; ERequestBody[ERequestBody["Nonce"] = 1] = "Nonce"; ERequestBody[ERequestBody["Message"] = 2] = "Message"; })(ERequestBody = exports.ERequestBody || (exports.ERequestBody = {})); var ERequestResponse; (function (ERequestResponse) { ERequestResponse["SUCCESS"] = "SUCCESS"; ERequestResponse["TIMEOUT"] = "TIMEOUT"; ERequestResponse["CACHE_ERROR"] = "CACHE_ERROR"; })(ERequestResponse = exports.ERequestResponse || (exports.ERequestResponse = {})); class ZMQRequest { constructor(aReceiverEndpoint, aErrorHandlers) { this.mCancellableDelay = new Delay_1.CancellableDelay(); this.mPendingRequests = new Map(); this.mRequestNonce = -1; this.mSafeToSend = true; this.mSendQueue = new typescript_collections_1.Queue(); this.mRoundTripMax = Config_1.default.MaximumLatency * 2; // Send + response latency this.mEndpoint = aReceiverEndpoint; this.mErrorHandlers = aErrorHandlers ?? Errors_1.DEFAULT_ZMQ_REQUEST_ERROR_HANDLERS; this.mOurUniqueId = uniqid_1.default(); this.Open(); } get ResponseTimeout() { return Config_1.default.HeartBeatInterval; } get Endpoint() { return this.mEndpoint; } AssertRequestProcessed(aRequestId, aRequest) { const lResolver = this.mPendingRequests.get(aRequestId); if (lResolver) { lResolver({ ResponseType: ERequestResponse.TIMEOUT, MessageNonce: aRequestId, RequestBody: aRequest, }); } } GenerateRequestResult(aMessage, aNonce) { let lRequestResult; if (this.IsErrorMessage(aMessage)) { lRequestResult = { ResponseType: ERequestResponse.CACHE_ERROR, Endpoint: this.mEndpoint, MessageNonce: Number(aNonce), }; } else { lRequestResult = { ResponseType: ERequestResponse.SUCCESS, Response: aMessage.toString(), }; } return lRequestResult; } HandleZMQSendError(aError, aRequest) { if (aError && aError.code && aError.code === "EAGAIN") { const lHighWaterMarkWarning = { Requester: aRequest[ERequestBody.RequesterId], Nonce: Number(aRequest[ERequestBody.Nonce]), Message: aRequest[ERequestBody.Message], }; this.mErrorHandlers.HighWaterMarkWarning(lHighWaterMarkWarning); } else { throw aError; } } IsErrorMessage(aMessage) { return aMessage === ZMQResponse_1.RESPONSE_CACHE_EXPIRED; } async ManageRequest(aRequestId, aRequest) { const lMaximumSendTime = Date.now() + this.mRoundTripMax; await this.mCancellableDelay.Create(this.ResponseTimeout); while (this.mPendingRequests.has(aRequestId) && Date.now() < lMaximumSendTime) { await this.QueueSend(aRequest); await this.mCancellableDelay.Create(this.ResponseTimeout); } this.AssertRequestProcessed(aRequestId, aRequest); } Open() { this.mDealer = new zmq.Dealer; this.mDealer.sendTimeout = 0; this.mDealer.connect(this.mEndpoint); this.ResponseHandler(); } async ProcessSend() { const lNextSend = this.mSendQueue.peek(); if (lNextSend && this.mSafeToSend) { this.mSafeToSend = false; this.mSendQueue.dequeue(); try { await this.mDealer.send(lNextSend.Request); } catch (aError) { this.HandleZMQSendError(aError, lNextSend.Request); } lNextSend.Resolve(); this.mSafeToSend = true; this.ProcessSend(); } } ProcessZmqReceive(nonce, msg) { const lRequestNonce = Number(nonce.toString()); const lMessage = msg.toString(); const lMessageCaller = this.mPendingRequests.get(lRequestNonce); if (lMessageCaller) { lMessageCaller(this.GenerateRequestResult(lMessage, lRequestNonce)); this.mPendingRequests.delete(lRequestNonce); } } QueueSend(aRequest) { let lResolver; const lPromise = new Promise((aResolve) => { lResolver = aResolve; }); this.mSendQueue.enqueue({ Request: aRequest, Resolve: lResolver, }); this.ProcessSend(); return lPromise; } async ResponseHandler() { for await (const [nonce, msg] of this.mDealer) { if (this.mDealer) { this.ProcessZmqReceive(nonce, msg); } } } async SendRequest(aRequest) { const lRequestId = Number(aRequest[ERequestBody.Nonce]); await this.QueueSend(aRequest); // Can potentially move this inside of ManageRequest loop this.ManageRequest(lRequestId, aRequest); return new Promise((aResolve) => { this.mPendingRequests.set(lRequestId, aResolve); }); } Close() { this.mDealer.linger = 0; this.mDealer.close(); this.mDealer = undefined; this.mCancellableDelay.Clear(); } async Send(aData) { const lRequestId = ++this.mRequestNonce; const lRequest = [ this.mOurUniqueId, lRequestId.toString(), aData, ]; return this.SendRequest(lRequest); } } exports.ZMQRequest = ZMQRequest; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWk1RUmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL1NyYy9aTVFSZXF1ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtRUFBK0M7QUFDL0Msb0RBQTRCO0FBQzVCLDRDQUE4QjtBQUM5QixzREFBOEI7QUFDOUIscUNBSWtCO0FBQ2xCLHlDQUFpRDtBQUNqRCwrQ0FBdUQ7QUFXdkQsSUFBWSxZQUtYO0FBTEQsV0FBWSxZQUFZO0lBRXBCLDZEQUFXLENBQUE7SUFDWCxpREFBSyxDQUFBO0lBQ0wscURBQU8sQ0FBQTtBQUNYLENBQUMsRUFMVyxZQUFZLEdBQVosb0JBQVksS0FBWixvQkFBWSxRQUt2QjtBQUVELElBQVksZ0JBS1g7QUFMRCxXQUFZLGdCQUFnQjtJQUV4Qix1Q0FBbUIsQ0FBQTtJQUNuQix1Q0FBbUIsQ0FBQTtJQUNuQiwrQ0FBMkIsQ0FBQTtBQUMvQixDQUFDLEVBTFcsZ0JBQWdCLEdBQWhCLHdCQUFnQixLQUFoQix3QkFBZ0IsUUFLM0I7QUFzQkQsTUFBYSxVQUFVO0lBYW5CLFlBQW1CLGlCQUF5QixFQUFFLGNBQXlDO1FBWHRFLHNCQUFpQixHQUFxQixJQUFJLHdCQUFnQixFQUFFLENBQUM7UUFLN0QscUJBQWdCLEdBQWtDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDckUsa0JBQWEsR0FBVyxDQUFDLENBQUMsQ0FBQztRQUUzQixnQkFBVyxHQUFZLElBQUksQ0FBQztRQUNuQixlQUFVLEdBQTJCLElBQUksOEJBQUssRUFBRSxDQUFDO1FBSTlELElBQUksQ0FBQyxhQUFhLEdBQUcsZ0JBQU0sQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLENBQUMsMEJBQTBCO1FBQzFFLElBQUksQ0FBQyxTQUFTLEdBQUcsaUJBQWlCLENBQUM7UUFDbkMsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLElBQUksMkNBQWtDLENBQUM7UUFDM0UsSUFBSSxDQUFDLFlBQVksR0FB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