reliable-zeromq
Version:
A collection of reliable zeromq messaging constructs
414 lines • 42.8 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 });
const ava_1 = __importDefault(require("ava"));
const sinon_1 = __importDefault(require("sinon"));
const ts_mock_imports_1 = require("ts-mock-imports");
const zmq = __importStar(require("zeromq"));
const Delay_1 = require("../../../Src/Utils/Delay");
const JSONBigInt_1 = __importDefault(require("../../../Src/Utils/JSONBigInt"));
const ZMQPublisher_1 = require("../../../Src/ZMQPublisher");
const ZMQRequest = __importStar(require("../../../Src/ZMQRequest"));
const ZMQRequest_1 = require("../../../Src/ZMQRequest");
const ZMQSubscriber_1 = require("../../../Src/ZMQSubscriber/ZMQSubscriber");
const AsyncTools_1 = require("../../Helpers/AsyncTools");
const DummyEndpoints_data_1 = require("../../Helpers/DummyEndpoints.data");
const test = ava_1.default;
test.before((t) => {
// Unnecessary
});
test.beforeEach((t) => {
const lResolvers = [];
function FakeIterator() {
return {
async next() {
return new Promise((aResolve) => {
lResolvers.push(aResolve);
});
},
};
}
const lMockManager = ts_mock_imports_1.ImportMock.mockClass(zmq, "Subscriber");
// @ts-ignore
const lAsyncIteratorMock = lMockManager.mock(Symbol.asyncIterator);
lAsyncIteratorMock.callsFake(FakeIterator);
const lRequestMock = ts_mock_imports_1.ImportMock.mockClass(ZMQRequest, "ZMQRequest");
t.context =
{
RequestMock: lRequestMock,
TestData: [
{
a: 100n,
b: 20n,
c: 0.5,
d: [
5n,
"myFunc()",
],
},
],
StatusEndpoint: {
PublisherAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress,
RequestAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.RequestAddress,
},
WeatherEndpoint: {
PublisherAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.WEATHER_UPDATES.PublisherAddress,
RequestAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.WEATHER_UPDATES.RequestAddress,
},
SendToReceiver: (aIndex, aMessage) => {
lResolvers[aIndex]({ value: aMessage, done: false });
},
};
});
test.afterEach((t) => {
sinon_1.default.restore();
ts_mock_imports_1.ImportMock.restore();
});
test.serial("Start, Subscribe, Recover, Close", async (t) => {
const lTestDataResult = {
[DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress]: [],
[DummyEndpoints_data_1.DUMMY_ENDPOINTS.WEATHER_UPDATES.PublisherAddress]: [],
};
const lStatusTopics = lTestDataResult[DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress];
const lWeatherTopics = lTestDataResult[DummyEndpoints_data_1.DUMMY_ENDPOINTS.WEATHER_UPDATES.PublisherAddress];
lStatusTopics[0]
= { topic: "TopicA", subId: 0, test: [{ data: "myTopicAMessage", result: undefined, publish: undefined }] };
lStatusTopics[1]
= { topic: "TopicB", subId: 0, test: [
{ data: "myTopicBMessage1", result: undefined, publish: undefined },
{ data: "myTopicBMessage2", result: undefined, publish: undefined },
{ data: "myTopicBMessage3", result: undefined, publish: undefined },
{ data: "myTopicBMessage4", result: undefined, publish: undefined },
{ data: "myTopicBMessage5", result: undefined, publish: undefined },
] };
lStatusTopics[2]
= { topic: "TopicC", subId: 0, test: [{ data: "myTopicCMessage", result: undefined, publish: undefined }] };
lWeatherTopics[0]
= { topic: "Sydney", subId: 0, test: [{ data: "Sunny", result: undefined, publish: undefined }] };
lWeatherTopics[1]
= { topic: "Newcastle", subId: 0, test: [{ data: "Cloudy", result: undefined, publish: undefined }] };
let lSoloPublisher = undefined;
let lIteration = 0;
const lNewIterator = (aValue) => {
const lIterationOld = lIteration++;
let lNextCount = 0;
return {
async next() {
return new Promise((resolve) => {
lInsertCallback(resolve, lIterationOld, lNextCount++);
});
},
};
};
const lInsertCallback = (aFunc, aIteration, aCount) => {
const lFunc = (aMsg) => {
return aFunc({ value: aMsg, done: false });
};
function InsertByCount(aEndpoint, aCount) {
const lTopics = lTestDataResult[aEndpoint];
let x = 0;
let y = 0;
let incrementX = false;
for (let i = 0; i < aCount; ++i) {
const lNextPosition = lTopics[x].test[y + 1];
if (lNextPosition) {
++y;
}
else {
if (incrementX) {
++x;
y = 0;
incrementX = false;
}
else {
incrementX = true; // Let's us duplicate the last message and close the iterator
}
}
}
if (lTopics[x]) {
if (!incrementX) {
lTopics[x].test[y].publish = function firstTimePublish(aMsg) {
return aFunc({ value: aMsg, done: false });
};
}
else {
lTopics[x].test[y].publish = function duplicatePublish(aMsg) {
return aFunc({ value: aMsg, done: false });
};
}
}
}
switch (aIteration) {
case 0:
lSoloPublisher = lFunc;
break;
case 1:
InsertByCount(DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress, aCount);
break;
case 2:
InsertByCount(DummyEndpoints_data_1.DUMMY_ENDPOINTS.WEATHER_UPDATES.PublisherAddress, aCount);
break;
default:
throw new Error("Unexpected call to create asyncIterator");
}
};
const lZmqSubscriberMock = ts_mock_imports_1.ImportMock.mockClass(zmq, "Subscriber");
// @ts-ignore
const lIteratorStub = lZmqSubscriberMock.mock(Symbol.asyncIterator, lNewIterator);
lIteratorStub.callsFake(lNewIterator);
// END SETUP
const lSubscriber = new ZMQSubscriber_1.ZMQSubscriber();
let lCalled = false;
lSubscriber.Subscribe({
PublisherAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress,
RequestAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.RequestAddress,
}, "myFirstTopic", (aMsg) => {
t.is(aMsg, JSONBigInt_1.default.Stringify(t.context.TestData));
lCalled = true;
});
lSoloPublisher([
"myFirstTopic",
ZMQPublisher_1.EMessageType.PUBLISH,
"0",
JSONBigInt_1.default.Stringify(t.context.TestData),
]);
await AsyncTools_1.YieldToEventLoop();
t.true(lCalled);
t.is(lSubscriber["mEndpoints"].size, 1);
lSubscriber.Close();
t.is(lSubscriber["mEndpoints"].size, 0);
const lSubscribe = (aEndpoint, aIndex) => {
const lTopic = lTestDataResult[aEndpoint.PublisherAddress][aIndex];
let lCallNumber = 0;
lTopic.subId = lSubscriber.Subscribe(aEndpoint, lTopic.topic, (aMsg) => {
t.assert(lCallNumber < lTestDataResult[aEndpoint.PublisherAddress][aIndex].test.length);
lTestDataResult[aEndpoint.PublisherAddress][aIndex].test[lCallNumber++].result = aMsg;
});
};
lSubscribe({
PublisherAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress,
RequestAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.RequestAddress,
}, 0);
lSubscribe(t.context.StatusEndpoint, 1);
lSubscribe(t.context.StatusEndpoint, 2);
lSubscribe(t.context.WeatherEndpoint, 0);
lSubscribe(t.context.WeatherEndpoint, 1);
for (const aEndpoint in lTestDataResult) {
const lTopics = lTestDataResult[aEndpoint];
for (let aIndex = 0; aIndex < lTopics.length; ++aIndex) {
const lTopic = lTopics[aIndex];
for (let i = 0; i < lTopic.test.length; ++i) {
await AsyncTools_1.YieldToEventLoop();
lTopic.test[i].publish([
lTopic.topic,
ZMQPublisher_1.EMessageType.PUBLISH,
(i).toString(),
lTopic.test[i].data,
]);
if (i === lTopic.test.length - 1) {
// Duplicate final message to test drop handling
await AsyncTools_1.YieldToEventLoop();
lTopic.test[i].publish([
lTopic.topic,
ZMQPublisher_1.EMessageType.PUBLISH,
(i).toString(),
"DUPLICATE MESSAGE: IGNORE DATA",
]);
}
}
}
}
await AsyncTools_1.YieldToEventLoop();
for (const aEndpoint in lTestDataResult) {
const lTopics = lTestDataResult[aEndpoint];
for (let aIndex = 0; aIndex < lTopics.length; ++aIndex) {
const lTopic = lTopics[aIndex];
for (let i = 0; i < lTopic.test.length; ++i) {
t.is(lTopic.test[i].data, lTopic.test[i].result);
}
}
}
for (const aEndpoint in lTestDataResult) {
const lTopics = lTestDataResult[aEndpoint];
for (let aIndex = 0; aIndex < lTopics.length; ++aIndex) {
const lTopic = lTopics[aIndex];
lSubscriber.Unsubscribe(lTopic.subId);
}
t.is(lSubscriber["mEndpoints"].get(aEndpoint), undefined);
}
});
test.serial("Message Recovery & Heartbeats", async (t) => {
const clock = sinon_1.default.useFakeTimers();
const lCustomCacheErrors = [];
const lCustomDroppedMessages = [];
const lCustomSubIds = [];
const lCustomResults = [];
const lDefaultSubIds = [];
const lDefaultResults = [];
const lCustomSubscriber = new ZMQSubscriber_1.ZMQSubscriber({
CacheError: (aError) => { lCustomCacheErrors.push(aError); },
DroppedMessageWarn: (aWarning) => { lCustomDroppedMessages.push(aWarning); },
});
const lDefaultSubscriber = new ZMQSubscriber_1.ZMQSubscriber();
lCustomSubIds[0] = lCustomSubscriber.Subscribe({
PublisherAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress,
RequestAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.RequestAddress,
}, "TopicToTest", (aMsg) => { lCustomResults.push(aMsg); });
lCustomSubIds[1] = lCustomSubscriber.Subscribe(t.context.WeatherEndpoint, "Sydney", (aMsg) => { lCustomResults.push(aMsg); });
lDefaultSubIds[0] = lDefaultSubscriber.Subscribe({
PublisherAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.PublisherAddress,
RequestAddress: DummyEndpoints_data_1.DUMMY_ENDPOINTS.STATUS_UPDATES.RequestAddress,
}, "TopicToTest", (aMsg) => { lDefaultResults.push(aMsg); });
const lRequestMock = t.context.RequestMock;
const lSendMock = lRequestMock.mock("Send");
const lStatusResponse = [
["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, 0, "Hello1"],
["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, 1, "Hello2"],
["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, 2, "Hello3"],
];
const lWeatherResponse = [
["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, 0, "Rainy"],
["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, 1, "Misty"],
["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, 2, "Cloudy"],
["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, 3, "Sunny"],
[ZMQPublisher_1.PUBLISHER_CACHE_EXPIRED],
];
const lStatusSuccess = {
ResponseType: ZMQRequest_1.ERequestResponse.SUCCESS,
Response: JSONBigInt_1.default.Stringify(lStatusResponse),
};
const lStatusRecoveryPromise = new Promise((aResolve) => {
Delay_1.Delay(50).then(() => {
aResolve(lStatusSuccess);
});
});
const lWeatherSuccess = {
ResponseType: ZMQRequest_1.ERequestResponse.SUCCESS,
Response: JSONBigInt_1.default.Stringify(lWeatherResponse),
};
const lFailedRecovery = {
ResponseType: ZMQRequest_1.ERequestResponse.TIMEOUT,
MessageNonce: 1337,
RequestBody: ["bish", "bash", "bosh"],
};
lSendMock
.onCall(0).returns(lStatusRecoveryPromise)
.onCall(1).returns(Promise.resolve(lWeatherSuccess))
.onCall(2).returns(Promise.resolve(lFailedRecovery))
.onCall(3).returns(Promise.resolve(lStatusSuccess));
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(0, ["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, "3", "Hello4"]); // Send update with nonce 4
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults[0], "Hello4");
t.is(lSendMock.getCall(0).args[0], JSONBigInt_1.default.Stringify(["TopicToTest", 0, 1, 2]));
t.deepEqual(lCustomDroppedMessages[0], { Topic: "TopicToTest", Nonces: [0, 1, 2] });
t.context.SendToReceiver(3, ["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, "1", "Hello2"]); // Send nonce 2 before recovery response
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults[1], "Hello2");
clock.tick(50); // Trigger recovery response to resolve
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults[2], "Hello1");
t.is(lCustomResults[3], "Hello3");
t.is(lCustomResults[4], undefined);
t.is(lCustomResults.length, 4);
t.context.SendToReceiver(4, ["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, "3", "DUP_NONCE"]); // Send duplicate messages
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(5, ["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, "1", "DUP_NONCE"]); // Send duplicate messages
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults.length, 4);
t.is(lCustomResults[4], undefined);
t.context.SendToReceiver(1, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "-1", ""]);
t.is(lCustomSubscriber["mEndpoints"].get(DummyEndpoints_data_1.DUMMY_ENDPOINTS.WEATHER_UPDATES.PublisherAddress)
.TopicEntries.get("Sydney").Nonce, -1);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(7, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "4", ""]);
await AsyncTools_1.YieldToEventLoop();
t.is(lSendMock.getCall(1).args[0], JSONBigInt_1.default.Stringify(["Sydney", 0, 1, 2, 3, 4]));
t.is(lCustomResults[4], "Rainy");
t.is(lCustomResults[5], "Misty");
t.is(lCustomResults[6], "Cloudy");
t.is(lCustomResults[7], "Sunny");
t.is(lCustomResults[8], undefined);
t.deepEqual(lCustomCacheErrors[0], {
Endpoint: t.context.WeatherEndpoint,
Topic: "Sydney",
MessageNonce: 4,
});
t.is(lCustomResults.length, 8);
lCustomSubIds[2] = lCustomSubscriber.Subscribe(t.context.WeatherEndpoint, "Sydney", (aMsg) => { lCustomResults.push(aMsg); });
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(8, ["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, "3", "Overcast"]);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(9, ["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, "2", "Sunny"]);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(10, ["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, "1", "Cloudy"]);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(11, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "0", ""]);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(12, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "3", ""]);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(13, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "2", ""]);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(14, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "1", ""]);
// console.log(lResults);
t.is(lCustomResults.length, 8);
await AsyncTools_1.YieldToEventLoop();
t.context.SendToReceiver(15, ["Sydney", ZMQPublisher_1.EMessageType.PUBLISH, "5", "NewWeather"]);
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults[8], "NewWeather");
t.is(lCustomResults[9], "NewWeather");
// Test ZMQRequest.Send returns TRequestTimeOut
t.context.SendToReceiver(16, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "6", ""]);
await AsyncTools_1.YieldToEventLoop();
t.is(lSendMock.getCall(2).args[0], JSONBigInt_1.default.Stringify(["Sydney", 6]));
t.deepEqual(lCustomCacheErrors[1], {
Endpoint: t.context.WeatherEndpoint,
Topic: "Sydney",
MessageNonce: 6,
});
// Unknown Message Type Drops Silently
t.is(lCustomResults.length, 10);
t.is(lCustomCacheErrors.length, 2);
t.context.SendToReceiver(6, ["TopicToTest", "UNKNOWN", "20", ""]);
await AsyncTools_1.YieldToEventLoop();
// DroppedMessageWarn suppressed by default handlers
t.context.SendToReceiver(2, ["TopicToTest", ZMQPublisher_1.EMessageType.PUBLISH, "3", "Hello4"]); // Send update with nonce 4
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults.length, 10);
t.is(lCustomCacheErrors.length, 2);
lCustomSubscriber.Unsubscribe(lCustomSubIds[0]);
lCustomSubscriber.Unsubscribe(lCustomSubIds[1]);
lCustomSubscriber.Unsubscribe(lCustomSubIds[2]);
lCustomSubscriber.Unsubscribe(lDefaultSubIds[0]);
lCustomSubscriber.Unsubscribe(1337); // In current version unsubscribing from non-existent subscription is a no-op
// Send messages after unsubscribe
t.is(lCustomResults.length, 10);
t.is(lCustomCacheErrors.length, 2);
t.context.SendToReceiver(18, ["TopicToTest", ZMQPublisher_1.EMessageType.HEARTBEAT, "20", ""]);
t.context.SendToReceiver(17, ["Sydney", ZMQPublisher_1.EMessageType.HEARTBEAT, "20", ""]);
await AsyncTools_1.YieldToEventLoop();
t.is(lCustomResults.length, 10);
t.is(lCustomCacheErrors.length, 2);
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWk1RU3Vic2NyaWJlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vVGVzdC9TcmMvWk1RU3Vic2NyaWJlci9aTVFTdWJzY3JpYmVyLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsOENBQWdEO0FBQ2hELGtEQUEwQjtBQUMxQixxREFBMEQ7QUFDMUQsNENBQThCO0FBRTlCLG9EQUFpRDtBQUNqRCwrRUFBdUQ7QUFDdkQsNERBQXFHO0FBQ3JHLG9FQUFzRDtBQUN0RCx3REFBZ0c7QUFDaEcsNEVBQWlHO0FBQ2pHLHlEQUE0RDtBQUM1RCwyRUFBb0U7QUFZcEUsTUFBTSxJQUFJLEdBQWdDLGFBQXNDLENBQUM7QUFFakYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQWlDLEVBQVEsRUFBRTtJQUVwRCxjQUFjO0FBQ2xCLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQWlDLEVBQVEsRUFBRTtJQUV4RCxNQUFNLFVBQVUsR0FBa0QsRUFBRSxDQUFDO0lBQ3JFLFNBQVMsWUFBWTtRQUVqQixPQUFPO1lBQ0gsS0FBSyxDQUFDLElBQUk7Z0JBRU4sT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLFFBQWdELEVBQVEsRUFBRTtvQkFFMUUsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDOUIsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDO1NBQ0osQ0FBQztJQUNOLENBQUM7SUFFRCxNQUFNLFlBQVksR0FBZ0MsNEJBQVUsQ0FBQyxTQUFTLENBQWlCLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMxRyxhQUFhO0lBQ2IsTUFBTSxrQkFBa0IsR0FBb0IsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDcEYsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFD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