public void Publish(string tickerSymbol, ITradeEvent @event) { var eventType = @event.ToTradeEventType(); var topic = ToTopic(tickerSymbol, eventType); _mediator.Tell(new Publish(topic, @event)); }
public async override Task OnEvent(ITradeEvent @event) { //process trade... await Task.Delay(1000); var isRejected = _rand.Next(0, 4) == 0; if (isRejected) { await Emit(new TradeRejected() { TradeId = @event.TradeId }); _logger.LogInformation($"Trade {@event.TradeId} has been rejected"); } else { await Emit(new TradeValidated() { TradeId = @event.TradeId }); _logger.LogInformation($"Trade {@event.TradeId} has been validated"); } }
private void VerifySerialization(ITradeEvent trade) { var serializer = Sys.Serialization.FindSerializerFor(trade).As <TradeEventSerializer>(); var serialized = serializer.ToBinary(trade); var manifest = serializer.Manifest(trade); var deserialized = serializer.FromBinary(serialized, manifest); deserialized.Should().Be(trade); }
private void ProcessBid(Bid bid, Confirmation confirmation) { var events = _matchingEngine.WithBid(bid); var persistableEvents = new ITradeEvent[] { bid }.Concat <ITradeEvent>(events); // bid needs to go before Fill / Match _log.Info("[{0}][{1}] - {2} units @ {3} per unit", TickerSymbol, bid.ToTradeEventType(), bid.BidQuantity, bid.BidPrice); PersistAll(persistableEvents, @event => { PersistTrade(@event, confirmation); }); }
public async override Task OnEvent(ITradeEvent @event) { await Emit(new TradeBooked() { TradeId = @event.TradeId, TradeBook = _tradeBooks.Random() }); _logger.LogInformation($"Trade {@event.TradeId} has been booked"); }
private void ProcessAsk(Ask ask, Confirmation confirmation) { var events = _matchingEngine.WithAsk(ask); var persistableEvents = new ITradeEvent[] { ask }.Concat <ITradeEvent>(events); // ask needs to go before Fill / Match _log.Info("[{0}][{1}] - {2} units @ {3} per unit", TickerSymbol, ask.ToTradeEventType(), ask.AskQuantity, ask.AskPrice); PersistAll(persistableEvents, @event => { PersistTrade(@event, confirmation); }); }
public void Publish(string tickerSymbol, ITradeEvent @event) { var eventType = @event.ToTradeEventType(); EnsureSub(eventType); foreach (var sub in _subscribers[eventType]) { sub.Tell(@event); } }
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()); } }
public async override Task OnEvent(ITradeEvent @event) { var trade = await _repository.Get(@event.TradeId); @event.Handle(trade); await _repository.Update(trade); if (@event is TradeCreated) { _logger.LogInformation($"Trade {@event.TradeId} has been acknowledged"); await Emit(new TradeAcknowleged() { TradeId = @event.TradeId }); } }
public static TradeEventType ToTradeEventType(this ITradeEvent @event) { switch (@event) { case Bid b: return(TradeEventType.Bid); case Ask a: return(TradeEventType.Ask); case Fill f: return(TradeEventType.Fill); case Match m: return(TradeEventType.Match); default: throw new ArgumentOutOfRangeException($"[{@event}] is not a supported trade event type.", nameof(@event)); } }
public Task Emit(ITradeEvent @event) { using (var connection = _connectionFactory.CreateConnection()) { using (var channel = connection.CreateModel()) { var payload = JsonConvert.SerializeObject(@event); var body = Encoding.UTF8.GetBytes(payload); channel.BasicPublish( exchange: _exchangeName, routingKey: EventServiceName, basicProperties: null, body: body ); _logger.LogInformation($"Emitted event {@event.GetType()}"); } } return(Task.CompletedTask); }
public void FireEvent(ITradeEvent fired) { if (fired == null) throw new ArgumentNullException(nameof(fired)); var key = fired.GetType(); if (!delegates.ContainsKey(key)) return; EventCallback callbacks; while (!delegates.TryGetValue(key, out callbacks)) { } try { callbacks.Invoke(fired); } catch (Exception ex) { Logger.Error(ex); } }
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()); }); }
public void ShouldMatchEventWithTradeType(ITradeEvent tradeEvent, TradeEventType expectedType) { tradeEvent.ToTradeEventType().Should().Be(expectedType); }
private void Handler(ITradeEvent tradeEvent) { pubsubservice.Publish("fzf003", tradeEvent, true); }
public void ShouldSerializeTradeEvent(ITradeEvent trade) { VerifySerialization(trade); }
public abstract Task OnEvent(ITradeEvent @event);
public void Publish(string topic, ITradeEvent @event, bool sendOneMessageToEachGroup = false) { _mediator.Tell(new Publish(topic, @event, sendOneMessageToEachGroup)); }
public void Send(string actorpath, ITradeEvent @event, bool localAffinity = false) { _mediator.Tell(new Send(actorpath, @event, localAffinity)); }
private static void LogTradeEvent(object sender, ITradeEvent e) { Console.WriteLine("trade event:\n" + e.ToString()); }