private void PersistTrade(ITradeEvent @event, Confirmation confirmation)
        {
            if (confirmation != null && (@event is Ask || @event is Bid))
            {
                // need to use the ID of the original sender to satisfy the PersistenceSupervisor
                Sender.Tell(confirmation);
            }

            _publisher.Publish(TickerSymbol, @event);

            // Take a snapshot every N messages to optimize recovery time
            if (LastSequenceNr % SnapshotInterval == 0)
            {
                SaveSnapshot(_matchingEngine.GetSnapshot());
            }
        }
Пример #2
0
        private void Commands()
        {
            Command <ConfirmableMessage <Ask> >(a =>
            {
                // For the sake of efficiency - update orderbook and then persist all events
                var events            = _matchingEngine.WithAsk(a.Message);
                var persistableEvents = new ITradeEvent[] { a.Message }.Concat <ITradeEvent>(events); // ask needs to go before Fill / Match

                PersistAll(persistableEvents, @event =>
                {
                    _log.Info("[{0}][{1}] - {2} units @ {3} per unit", TickerSymbol, @event.ToTradeEventType(), a.Message.AskQuantity, a.Message.AskPrice);
                    if (@event is Ask)
                    {
                        // need to use the ID of the original sender to satisfy the PersistenceSupervisor
                        //_confirmationActor.Tell(new Confirmation(a.ConfirmationId, a.SenderId));
                    }
                    _publisher.Publish(TickerSymbol, @event);

                    // Take a snapshot every N messages to optimize recovery time
                    if (LastSequenceNr % SnapshotInterval == 0)
                    {
                        SaveSnapshot(_matchingEngine.GetSnapshot());
                    }
                });
            });

            Command <ConfirmableMessage <Bid> >(b =>
            {
                // For the sake of efficiency -update orderbook and then persist all events
                var events            = _matchingEngine.WithBid(b.Message);
                var persistableEvents = new ITradeEvent[] { b.Message }.Concat <ITradeEvent>(events); // bid needs to go before Fill / Match

                PersistAll(persistableEvents, @event =>
                {
                    _log.Info("[{0}][{1}] - {2} units @ {3} per unit", TickerSymbol, @event.ToTradeEventType(), b.Message.BidQuantity, b.Message.BidPrice);
                    if (@event is Bid)
                    {
                        //_confirmationActor.Tell(new Confirmation(b.ConfirmationId, PersistenceId));
                    }
                    _publisher.Publish(TickerSymbol, @event);

                    // Take a snapshot every N messages to optimize recovery time
                    if (LastSequenceNr % SnapshotInterval == 0)
                    {
                        SaveSnapshot(_matchingEngine.GetSnapshot());
                    }
                });
            });

            Command <SaveSnapshotSuccess>(success =>
            {
                //DeleteMessages(success.Metadata.SequenceNr);
                DeleteSnapshots(new SnapshotSelectionCriteria(success.Metadata.SequenceNr));
            });

            /*
             * Handle subscriptions directly in case we're using in-memory, local pub-sub.
             */
            CommandAsync <TradeSubscribe>(async sub =>
            {
                try
                {
                    var ack = await _subscriptionManager.Subscribe(sub.TickerSymbol, sub.Events, sub.Subscriber);
                    Context.Watch(sub.Subscriber);
                    sub.Subscriber.Tell(ack);
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Error while processing subscription {0}", sub);
                    sub.Subscriber.Tell(new TradeSubscribeNack(sub.TickerSymbol, sub.Events, ex.Message));
                }
            });

            CommandAsync <TradeUnsubscribe>(async unsub =>
            {
                try
                {
                    var ack = await _subscriptionManager.Unsubscribe(unsub.TickerSymbol, unsub.Events, unsub.Subscriber);
                    // leave DeathWatch intact, in case actor is still subscribed to additional topics
                    unsub.Subscriber.Tell(ack);
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Error while processing unsubscribe {0}", unsub);
                    unsub.Subscriber.Tell(new TradeUnsubscribeNack(unsub.TickerSymbol, unsub.Events, ex.Message));
                }
            });

            CommandAsync <Terminated>(async t =>
            {
                try
                {
                    var ack = await _subscriptionManager.Unsubscribe(TickerSymbol, t.ActorRef);
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Error while processing unsubscribe for terminated subscriber {0} for symbol {1}", t.ActorRef, TickerSymbol);
                }
            });

            Command <GetOrderBookSnapshot>(s =>
            {
                Sender.Tell(_matchingEngine.GetSnapshot());
            });
        }