UNPKG

reliable-zeromq

Version:

A collection of reliable zeromq messaging constructs

414 lines 42.8 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 }); 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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