예제 #1
0
        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);
        }
예제 #2
0
        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());
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
        }
예제 #7
0
        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();
            }
        }