public void ShouldSerializeEventSubject() { var changeCcyPairState = new ChangeCcyPairState("test", "FxConnect", CcyPairState.Active); var subject = _eventSerializer.GetSubject(changeCcyPairState); Assert.AreEqual("test.Active.FxConnect", subject); changeCcyPairState = new ChangeCcyPairState("test", null, CcyPairState.Passive); subject = _eventSerializer.GetSubject(changeCcyPairState); Assert.AreEqual("test.Passive", subject); var changeCcyPairPrice = new ChangeCcyPairPrice( ccyPairId: "test", market: "market", ask: 0.1, bid: 0.1, mid: 0.1, spread: 0.02 ); subject = _eventSerializer.GetSubject(changeCcyPairPrice); Assert.AreEqual("test.market", subject); }
public async Task ShouldSubscribeToSpecificSubject() { using (var publisherSocket = new PublisherSocket()) { publisherSocket.Bind(ToSubscribersEndpoint); var createEvent = new Func <string, string, Task>(async(streamId, market) => { var @event = new ChangeCcyPairPrice(streamId, market, 0.0, 0.0, 0.0, 0.0); var message = _eventSerializer.ToProducerMessage(@event); var eventId = new EventId(streamId, 0, string.IsNullOrEmpty(market) ? streamId : $"{streamId}.{market}", DateTime.Now.Ticks); publisherSocket.SendMoreFrame(message.Subject) .SendMoreFrame(_serializer.Serialize(eventId)) .SendFrame(_serializer.Serialize(message)); await Task.Delay(500); }); var subscribedToStreamId = "EUR/USD"; var subscribedToMarket = "Harmony"; var NOTsubscribedToStreamId = "EUR/GBP"; var NOTsubscribedToMarket = "FxConnect"; var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = $"{subscribedToStreamId}.{subscribedToMarket}", HeartbeatDelay = TimeSpan.FromSeconds(1), HeartbeatTimeout = TimeSpan.FromSeconds(1), }; var cache = new DynamicCache <string, CurrencyPair>(cacheConfiguration, LoggerForTests <DynamicCache <string, CurrencyPair> > .Default(), _eventSerializer); await cache.Run(); await Task.Delay(1000); await createEvent(NOTsubscribedToStreamId, NOTsubscribedToMarket); Assert.AreEqual(0, cache.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(NOTsubscribedToStreamId, subscribedToMarket); Assert.AreEqual(0, cache.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(subscribedToStreamId, NOTsubscribedToMarket); Assert.AreEqual(0, cache.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(subscribedToStreamId, subscribedToMarket); Assert.AreEqual(1, cache.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(subscribedToStreamId, string.Empty); Assert.AreEqual(1, cache.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); } }
public async Task ShouldApplyMultipleEvents() { using (var publisherSocket = new PublisherSocket()) { publisherSocket.Bind(ToSubscribersEndpoint); var streamId = "EUR/USD"; var createEvent = new Func <IEvent <String, CurrencyPair>, Task>(async(@event) => { var message = _eventSerializer.ToProducerMessage(@event); var eventId = new EventId(@event.EventStreamId, 0, @event.Subject, DateTime.Now.Ticks); publisherSocket.SendMoreFrame(message.Subject) .SendMoreFrame(_serializer.Serialize(eventId)) .SendFrame(_serializer.Serialize(message)); await Task.Delay(200); }); var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = string.Empty, HeartbeatDelay = TimeSpan.FromSeconds(1), HeartbeatTimeout = TimeSpan.FromSeconds(1), }; var cache = new DynamicCache <string, CurrencyPair>(cacheConfiguration, LoggerForTests <DynamicCache <string, CurrencyPair> > .Default(), _eventSerializer); await cache.Run(); await Task.Delay(2000); var priceEvent = new ChangeCcyPairPrice(streamId, "FxConnect", 0.0, 0.0, 0.0, 0.0); await createEvent(priceEvent); var changeStateClose = new ChangeCcyPairState(streamId, "FxConnect", CcyPairState.Passive); await createEvent(changeStateClose); Assert.AreEqual(1, cache.Items.Count()); Assert.AreEqual(CcyPairState.Passive, cache.Items.First().State); Assert.AreEqual(2, cache.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await cache.Destroy(); } }
public async Task ShouldSwitchToStaledState() { using (var publisherSocket = new PublisherSocket()) { publisherSocket.Bind(ToSubscribersEndpoint); var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = string.Empty, HeartbeatDelay = TimeSpan.FromSeconds(5), HeartbeatTimeout = TimeSpan.FromSeconds(1), IsStaleTimeout = TimeSpan.FromSeconds(2) }; var cache = new DynamicCache <string, CurrencyPair>(cacheConfiguration, LoggerForTests <DynamicCache <string, CurrencyPair> > .Default(), _eventSerializer); await cache.Run(); await WaitForCachesToCaughtUp(cache); Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState); Assert.AreEqual(true, cache.IsStaled); var @event = new ChangeCcyPairPrice("TEST", "TEST-Market", 0.0, 0.0, 0.0, 0.0); var message = _eventSerializer.ToProducerMessage(@event); var eventId = new EventId("TEST", 0, "TEST", DateTime.Now.Ticks); publisherSocket.SendMoreFrame(message.Subject) .SendMoreFrame(_serializer.Serialize(eventId)) .SendFrame(_serializer.Serialize(message)); await Task.Delay(200); Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState); Assert.AreEqual(false, cache.IsStaled); await Task.Delay(3500); Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState); Assert.AreEqual(true, cache.IsStaled); await Task.Delay(2000); Assert.AreEqual(true, cache.IsStaled); await cache.Destroy(); } }
private ChangeCcyPairPrice Next(string streamId, string market = "TEST") { var mid = _rand.NextDouble() * 10; var spread = _rand.NextDouble() * 2; var price = new ChangeCcyPairPrice( ask: mid + spread, bid: mid - spread, mid: mid, spread: spread, ccyPairId: streamId, market: market ) { EventStreamId = streamId }; return(price); }
public void ShouldSerializeEventSubject() { var serializer = new JsonNetSerializer(); var eventSerializer = new EventSerializer(serializer); var changeCcyPairState = new ChangeCcyPairState() { EventStreamId = "test", State = CcyPairState.Active, Market = "FxConnect" }; var subject = eventSerializer.GetSubject(changeCcyPairState); Assert.AreEqual("test.Active.FxConnect", subject); changeCcyPairState = new ChangeCcyPairState() { EventStreamId = "test", State = CcyPairState.Passive, }; subject = eventSerializer.GetSubject(changeCcyPairState); Assert.AreEqual("test.Passive.*", subject); var changeCcyPairPrice = new ChangeCcyPairPrice( ccyPairId: "test", market: "market", ask: 0.1, bid: 0.1, mid: 0.1, spread: 0.02 ); subject = eventSerializer.GetSubject(changeCcyPairPrice); Assert.AreEqual("test.market", subject); }
public async Task ShouldSubscribeToAllSubjects() { using (var publisherSocket = new PublisherSocket()) { publisherSocket.Bind(ToSubscribersEndpoint); await Task.Delay(200); var createEvent = new Func <string, string, Task>(async(streamId, market) => { var @event = new ChangeCcyPairPrice(streamId, market, 0.0, 0.0, 0.0, 0.0); var message = _eventSerializer.ToProducerMessage(@event); var eventId = new EventId(streamId, 0, string.IsNullOrEmpty(market) ? streamId : $"{streamId}.{market}", DateTime.Now.Ticks); publisherSocket.SendMoreFrame(message.Subject) .SendMoreFrame(_serializer.Serialize(eventId)) .SendFrame(_serializer.Serialize(message)); await Task.Delay(200); }); var euroDol = "EUR/USD"; var harmony = "Harmony"; var euroGbp = "EUR/GBP"; var fxconnect = "FxConnect"; var cacheConfigurationEuroDol = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = $"{euroDol}", HeartbeatDelay = TimeSpan.FromSeconds(1), HeartbeatTimeout = TimeSpan.FromSeconds(1), }; var cacheConfigurationAll = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint) { Subject = string.Empty, HeartbeatDelay = TimeSpan.FromSeconds(1), HeartbeatTimeout = TimeSpan.FromSeconds(1), }; var cacheEuroDol = new DynamicCache <string, CurrencyPair>(cacheConfigurationEuroDol, LoggerForTests <DynamicCache <string, CurrencyPair> > .Default(), _eventSerializer); var cacheAll = new DynamicCache <string, CurrencyPair>(cacheConfigurationAll, LoggerForTests <DynamicCache <string, CurrencyPair> > .Default(), _eventSerializer); await cacheEuroDol.Run(); await cacheAll.Run(); await WaitForCachesToCaughtUp(cacheEuroDol, cacheAll); Assert.AreEqual(DynamicCacheState.Connected, cacheEuroDol.CacheState); Assert.AreEqual(DynamicCacheState.Connected, cacheAll.CacheState); await createEvent(euroDol, harmony); Assert.AreEqual(1, cacheEuroDol.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); Assert.AreEqual(1, cacheAll.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(euroDol, fxconnect); await Task.Delay(500); Assert.AreEqual(2, cacheEuroDol.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); Assert.AreEqual(2, cacheAll.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(euroDol, string.Empty); Assert.AreEqual(3, cacheEuroDol.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); Assert.AreEqual(3, cacheAll.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(euroGbp, string.Empty); Assert.AreEqual(3, cacheEuroDol.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); Assert.AreEqual(4, cacheAll.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(euroGbp, harmony); Assert.AreEqual(3, cacheEuroDol.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); Assert.AreEqual(5, cacheAll.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await createEvent(euroGbp, fxconnect); Assert.AreEqual(3, cacheEuroDol.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); Assert.AreEqual(6, cacheAll.Items.SelectMany(ccy => ccy.AppliedEvents).Count()); await cacheEuroDol.Destroy(); await cacheAll.Destroy(); } }