reliable-zeromq
Version:
A collection of reliable zeromq messaging constructs
193 lines • 13.9 kB
JavaScript
"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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