public async Task ShouldCheckMinimumPerformance() { var eventIdProvider = new InMemoryEventIdProvider(); var serializer = new JsonNetSerializer(); var eventSerializer = new EventSerializer(serializer); var eventCache = new InMemoryEventCache(eventIdProvider, eventSerializer); var brokerConfiguration = new BrokerageServiceConfiguration() { HeartbeatEndpoint = HeartbeatEndpoint, StateOftheWorldEndpoint = StateOfTheWorldEndpoint, ToSubscribersEndpoint = ToSubscribersEndpoint, ToPublisherEndpoint = ToPublishersEndpoint }; var router = new BrokerageService(brokerConfiguration, eventCache, serializer); var marketConfiguration = new ProducerConfiguration() { RouterEndpoint = ToPublishersEndpoint, HearbeatEndpoint = HeartbeatEndpoint }; var market = new Market("FxConnect", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(10)); await router.Run(); await market.Run(); var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = string.Empty, HeartbeatDelay = TimeSpan.FromSeconds(10), HeartbeatTimeout = TimeSpan.FromSeconds(2) }; var cache = new DynamicCache <string, CurrencyPair>(cacheConfiguration, eventSerializer); await cache.Run(); //fire a little less than 300 events await Task.Delay(3000); await Task.WhenAll(new[] { router.Destroy(), market.Destroy(), cache.Destroy() }); var cacheItems = cache.GetItems().ToList(); var cacheItemsEvents = cacheItems.SelectMany(items => items.AppliedEvents).ToList(); //At least 3/4 events should be processed Assert.Greater((double)cacheItemsEvents.Count / (double)market.Prices.Count, 0.75); }
public async Task ShouldSubscribeToEventFeed() { var eventIdProvider = new InMemoryEventIdProvider(); var serializer = new JsonNetSerializer(); var eventSerializer = new EventSerializer(serializer); var eventCache = new InMemoryEventCache(eventIdProvider, eventSerializer); var brokerConfiguration = new BrokerageServiceConfiguration() { HeartbeatEndpoint = HeartbeatEndpoint, StateOftheWorldEndpoint = StateOfTheWorldEndpoint, ToSubscribersEndpoint = ToSubscribersEndpoint, ToPublisherEndpoint = ToPublishersEndpoint }; var router = new BrokerageService(brokerConfiguration, eventCache, serializer); var marketConfiguration = new ProducerConfiguration() { RouterEndpoint = ToPublishersEndpoint, HearbeatEndpoint = HeartbeatEndpoint }; var market1 = new Market("FxConnect", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(750)); var market2 = new Market("Harmony", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(750)); await router.Run(); await market1.Run(); await market2.Run(); //create an event cache await Task.Delay(2000); //Assert.Greater(router.Cache.Count(), 0); var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint); var cache = new DynamicCache <string, CurrencyPair>(cacheConfiguration, eventSerializer); var counter = 0; var cleanup = cache.OnItemChanged() .Connect() .Subscribe(_ => { counter++; }); await cache.Run(); await Task.Delay(2000); // Assert.AreEqual(router.Cache.Count(), counter); Assert.AreEqual(cache.GetItems().SelectMany(item => item.AppliedEvents).Count(), counter); //fxconnext & harmony Assert.AreEqual(2, cache.GetItems() .SelectMany(item => item.AppliedEvents) .Cast <ChangeCcyPairPrice>() .Select(ev => ev.Market) .Distinct() .Count()); cleanup.Dispose(); await Task.WhenAll(new[] { router.Destroy(), market1.Destroy(), market2.Destroy(), cache.Destroy() }); }
public async Task ShouldHandleDisconnectAndCacheRebuild() { var eventIdProvider = new InMemoryEventIdProvider(); var serializer = new JsonNetSerializer(); var eventSerializer = new EventSerializer(serializer); var eventCache = new InMemoryEventCache(eventIdProvider, eventSerializer); var brokerConfiguration = new BrokerageServiceConfiguration() { HeartbeatEndpoint = HeartbeatEndpoint, StateOftheWorldEndpoint = StateOfTheWorldEndpoint, ToSubscribersEndpoint = ToSubscribersEndpoint, ToPublisherEndpoint = ToPublishersEndpoint }; var router = new BrokerageService(brokerConfiguration, eventCache, serializer); var marketConfiguration = new ProducerConfiguration() { RouterEndpoint = ToPublishersEndpoint, HearbeatEndpoint = HeartbeatEndpoint }; var market1 = new Market("FxConnect", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(100)); var market2 = new Market("Harmony", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(100)); await router.Run(); await Task.Delay(1000); await market1.Run(); await market2.Run(); var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = string.Empty, HeartbeatDelay = TimeSpan.FromMilliseconds(500), HeartbeatTimeout = TimeSpan.FromSeconds(1) }; var cache = new DynamicCache <string, CurrencyPair>(cacheConfiguration, eventSerializer); var cacheProof = new DynamicCache <string, CurrencyPair>(cacheConfiguration, eventSerializer); await cacheProof.Run(); await cache.Run(); Assert.AreEqual(DynamicCacheState.NotConnected, cache.CacheState); Assert.AreEqual(DynamicCacheState.NotConnected, cacheProof.CacheState); await Task.Delay(2000); Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState); Assert.AreEqual(DynamicCacheState.Connected, cacheProof.CacheState); await Task.Delay(3000); Assert.AreEqual(cache.GetItems() .SelectMany(item => item.AppliedEvents) .Count(), cacheProof.GetItems() .SelectMany(item => item.AppliedEvents) .Count()); await router.Destroy(); await Task.Delay(cacheConfiguration.HeartbeatDelay); Assert.AreEqual(DynamicCacheState.Disconnected, cache.CacheState); Assert.AreEqual(DynamicCacheState.Disconnected, cacheProof.CacheState); router = new BrokerageService(brokerConfiguration, eventCache, serializer); await router.Run(); await Task.Delay(TimeSpan.FromSeconds(3)); Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState); Assert.AreEqual(DynamicCacheState.Connected, cacheProof.CacheState); await router.Destroy(); var cacheCCyPair = cache.GetItems().ToList(); var cacheProofCcyPair = cacheProof.GetItems().ToList(); Assert.AreEqual(cacheCCyPair.Count(), cacheProofCcyPair.Count()); Assert.AreEqual(cacheCCyPair.Count(), cacheProofCcyPair.Count()); foreach (var ccyPair in cacheCCyPair) { var proof = cacheProofCcyPair.First(ccy => ccy.Id == ccyPair.Id); Assert.AreEqual(ccyPair.Ask, proof.Ask); Assert.AreEqual(ccyPair.Bid, proof.Bid); Assert.AreEqual(ccyPair.Mid, proof.Mid); Assert.AreEqual(ccyPair.Spread, proof.Spread); } var brokerCacheEvents = (await eventCache.GetStreamBySubject(cacheConfiguration.Subject)).ToList(); var cacheEvents = cacheCCyPair.SelectMany(item => item.AppliedEvents).ToList(); var cacheProofEvents = cacheProofCcyPair.SelectMany(item => item.AppliedEvents).ToList(); Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count()); Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count()); Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count()); await Task.WhenAll(new[] { market1.Destroy(), market2.Destroy(), cache.Destroy() }); }
public async Task ShouldSubscribeToSubject() { //todo .NET COre MVC implem var eventIdProvider = new InMemoryEventIdProvider(); var serializer = new JsonNetSerializer(); var eventSerializer = new EventSerializer(serializer); var eventCache = new InMemoryEventCache(eventIdProvider, eventSerializer); var brokerConfiguration = new BrokerageServiceConfiguration() { HeartbeatEndpoint = HeartbeatEndpoint, StateOftheWorldEndpoint = StateOfTheWorldEndpoint, ToSubscribersEndpoint = ToSubscribersEndpoint, ToPublisherEndpoint = ToPublishersEndpoint }; var router = new BrokerageService(brokerConfiguration, eventCache, serializer); var marketConfiguration = new ProducerConfiguration() { RouterEndpoint = ToPublishersEndpoint, HearbeatEndpoint = HeartbeatEndpoint }; var market1 = new Market("FxConnect", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(750)); var market2 = new Market("Harmony", marketConfiguration, eventSerializer, TimeSpan.FromMilliseconds(750)); await router.Run(); await market1.Run(); await market2.Run(); var cacheConfigurationEuroDol = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = "EUR/USD" }; var cacheConfigurationEuroDolFxConnect = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = "EUR/USD.FxConnect" }; var cacheEuroDol = new DynamicCache <string, CurrencyPair>(cacheConfigurationEuroDol, eventSerializer); var cacheEuroDolFxConnect = new DynamicCache <string, CurrencyPair>(cacheConfigurationEuroDolFxConnect, eventSerializer); await cacheEuroDol.Run(); await cacheEuroDolFxConnect.Run(); //wait for a substential event stream await Task.Delay(5000); // Assert.Greater(router.Cache.Count(), 1); var ccyPairsCacheEuroDol = cacheEuroDol.GetItems() .SelectMany(item => item.AppliedEvents) .Select(item => item.Subject) .Distinct(); // EUR/USD.FxConnect & EUR/USD.Harmony Assert.AreEqual(2, ccyPairsCacheEuroDol.Count()); Assert.IsTrue(ccyPairsCacheEuroDol.All(subject => subject.EndsWith("FxConnect") || subject.EndsWith("Harmony"))); Assert.IsTrue(ccyPairsCacheEuroDol.All(subject => subject.StartsWith(cacheConfigurationEuroDol.Subject))); var ccyPairsCacheEuroDolFxConnect = cacheEuroDolFxConnect.GetItems() .SelectMany(item => item.AppliedEvents) .Select(item => item.Subject) .Distinct(); // EUR/USD.FxConnect Assert.AreEqual(1, ccyPairsCacheEuroDolFxConnect.Count()); Assert.AreEqual(cacheConfigurationEuroDolFxConnect.Subject, ccyPairsCacheEuroDolFxConnect.First()); await Task.WhenAll(new[] { router.Destroy(), market1.Destroy(), market2.Destroy(), cacheEuroDol.Destroy(), cacheEuroDolFxConnect.Destroy() }); }