public void Execute(Command command) { if (command == null) { throw new ArgumentNullException("command is null"); } if (command is CriarClienteCommand createCommand) { Cliente created = _repository.Create(createCommand.ToCustomerRecord()); _repository.unitOfWork.SaveChangesAsync(); _eventPublisher.PublishEvent(createCommand.ToCustomerEvent(created.Id)); } else if (command is AtualizarClienteCommand updateCommand) { Cliente record = _repository.GetById(updateCommand.Id); _repository.Update(updateCommand.ToCustomerRecord(record)); _repository.unitOfWork.SaveChangesAsync(); _eventPublisher.PublishEvent(updateCommand.ToCustomerEvent()); } else if (command is ExcluirClienteCommand deleteCommand) { _repository.Delete(deleteCommand.Id); _repository.unitOfWork.SaveChangesAsync(); _eventPublisher.PublishEvent(deleteCommand.ToCustomerEvent()); } }
public void ShouldPublishEvent() { var ringBuffer = new RingBuffer<LongEvent>(()=>new LongEvent(0), BufferSize); ringBuffer.SetGatingSequences(new NoOpEventProcessor(ringBuffer).Sequence); var eventPublisher = new EventPublisher<LongEvent>(ringBuffer); eventPublisher.PublishEvent(_translator); eventPublisher.PublishEvent(_translator); Assert.AreEqual(0L + ValueAdd, ringBuffer[0].Value); Assert.AreEqual(1L + ValueAdd, ringBuffer[1].Value); }
public void ShouldPublishEvent() { var ringBuffer = new RingBuffer <LongEvent>(() => new LongEvent(0), BufferSize); ringBuffer.SetGatingSequences(new NoOpEventProcessor(ringBuffer).Sequence); var eventPublisher = new EventPublisher <LongEvent>(ringBuffer); eventPublisher.PublishEvent(_translator); eventPublisher.PublishEvent(_translator); Assert.AreEqual(0L + ValueAdd, ringBuffer[0].Value); Assert.AreEqual(1L + ValueAdd, ringBuffer[1].Value); }
/// <summary> /// Handles incoming Bar data for persistence /// </summary> /// <param name="barDetail"></param> private void HandleBarData(BarDetail barDetail) { // Send incoming Bar to Disruptor _barPublisher.PublishEvent((barObject, sequenceNo) => { // Set bar details barObject.Bar.RequestId = barDetail.Bar.RequestId; barObject.Bar.Open = barDetail.Bar.Open; barObject.Bar.High = barDetail.Bar.High; barObject.Bar.Low = barDetail.Bar.Low; barObject.Bar.Close = barDetail.Bar.Close; barObject.Bar.Security = barDetail.Bar.Security; barObject.Bar.DateTime = barDetail.Bar.DateTime; barObject.Bar.MarketDataProvider = barDetail.Bar.MarketDataProvider; // Set bar parameters barObject.BarParameters.BarLength = barDetail.BarParameters.BarLength; barObject.BarParameters.Format = barDetail.BarParameters.Format; barObject.BarParameters.PriceType = barDetail.BarParameters.PriceType; barObject.BarParameters.PipSize = barDetail.BarParameters.PipSize; // Return updated object return(barObject); }); }
/// <summary> /// Consumes Execution messages from queue /// </summary> private void ConsumeExecutionMessages() { try { if (Logger.IsInfoEnabled) { Logger.Info("Starting execution message consumer", _type.FullName, "ConsumeExecutionMessages"); } while (true) { BasicDeliverEventArgs incomingMessage = (BasicDeliverEventArgs)_executionMessageConsumer.Queue.Dequeue(); // Add incoming message to Disruptor _executionMessagePublisher.PublishEvent((messageQueueObject, sequenceNo) => { // Initialize Parameter messageQueueObject.Message = new byte[incomingMessage.Body.Length]; // Copy information incomingMessage.Body.CopyTo(messageQueueObject.Message, 0); // Return updated object return(messageQueueObject); }); } } catch (Exception exception) { Logger.Error(exception, _type.FullName, "ConsumeExecutionMessages"); } }
/// <summary> /// Sends Profit Loss Report request to Server via Client /// </summary> /// <param name="parameters">Search parameters for the report</param> public void RequestProfitLossReport(Dictionary <TradeParameters, string> parameters) { try { if (Logger.IsDebugEnabled) { Logger.Debug("New Profit Report request received", _type.FullName, "RequestProfitLossReport"); } // Move request to disruptor _pnlReportRequestMessagePublisher.PublishEvent((requestParameters, sequenceNo) => { // Clear existing data requestParameters.Clear(); // Copy information foreach (KeyValuePair <TradeParameters, string> keyValuePair in parameters) { requestParameters.Add(keyValuePair.Key, keyValuePair.Value); } // Return updated object return(requestParameters); }); } catch (Exception exception) { Logger.Error(exception, _type.FullName, "RequestProfitLossReport"); } }
public static void Publish(object obj) { byte[] received = StreamConversion.ObjectToByteArray(obj); _publisher.PublishEvent((entry, sequenceNo) => { //copy byte to diruptor ring byte Buffer.BlockCopy(received, 0, entry, 0, received.Length); return(entry); }); }
public void ShouldPublishEvent() { const long valueAdd = 29L; var ringBuffer = new RingBuffer<LongEvent>(()=>new LongEvent(0), 32); ringBuffer.SetGatingSequences(new NoOpEventProcessor(ringBuffer).Sequence); var eventPublisher = new EventPublisher<LongEvent>(ringBuffer); Func<LongEvent, long, LongEvent> translator = (evt, seq) => { evt.Value = seq + valueAdd; return evt; }; eventPublisher.PublishEvent(translator); eventPublisher.PublishEvent(translator); Assert.AreEqual(0L + valueAdd, ringBuffer[0].Value); Assert.AreEqual(1L + valueAdd, ringBuffer[1].Value); }
public void Send <TEvent>(TEvent @event, long commitPosition, long preparePosition) { var eventPublisher = new EventPublisher <ReadModelEventStream>(ringBuffer); eventPublisher.PublishEvent((entry, pos) => { entry.CommitPosition = commitPosition; entry.PreparePosition = preparePosition; entry.Event = @event; return(entry); }); }
public void ShouldPublishEvent() { const long valueAdd = 29L; var ringBuffer = new RingBuffer <LongEvent>(() => new LongEvent(0), 32); ringBuffer.SetGatingSequences(new NoOpEventProcessor(ringBuffer).Sequence); var eventPublisher = new EventPublisher <LongEvent>(ringBuffer); Func <LongEvent, long, LongEvent> translator = (evt, seq) => { evt.Value = seq + valueAdd; return(evt); }; eventPublisher.PublishEvent(translator); eventPublisher.PublishEvent(translator); Assert.AreEqual(0L + valueAdd, ringBuffer[0].Value); Assert.AreEqual(1L + valueAdd, ringBuffer[1].Value); }
/// <summary> /// Handles incoming Historical Bar data for persistence /// </summary> /// <param name="historicBarData"></param> private void HandleHistoricBarData(HistoricBarData historicBarData) { // Send Historical Bar data to Disruptor _historicPublisher.PublishEvent((historicBarObject, sequenceNo) => { // Set parameters historicBarObject.ReqId = historicBarData.ReqId; historicBarObject.Bars = (Bar[])historicBarData.Bars.Clone(); historicBarObject.Security = historicBarData.Security; historicBarObject.DateTime = historicBarData.DateTime; historicBarObject.MarketDataProvider = historicBarData.MarketDataProvider; historicBarObject.BarsInformation = historicBarData.BarsInformation; // Return updated object return(historicBarObject); }); }
/// <summary> /// Publishes the event /// </summary> /// <param name="payload"></param> public static void Publish(InputPayload payload) { _publisher.PublishEvent((entry, sequenceNo) => { //check if payload is order or cancel order if (payload.IsOrder) { payload.Order.MemberWiseClone(entry.Order); entry.IsOrder = true; } else { payload.OrderCancellation.MemberWiseClone(entry.OrderCancellation); entry.IsOrder = false; } return(entry); }); }
/// <summary> /// Handles incoming Tick data for persistence /// </summary> /// <param name="tick"></param> private void HandleTickData(Tick tick) { // Send incoming Tick to Disruptor _tickPublisher.PublishEvent((tickObject, sequenceNo) => { // Set parameters tickObject.AskPrice = tick.AskPrice; tickObject.AskSize = tick.AskSize; tickObject.BidPrice = tick.BidPrice; tickObject.BidSize = tick.BidSize; tickObject.LastPrice = tick.LastPrice; tickObject.LastSize = tick.LastSize; tickObject.Security = tick.Security; tickObject.DateTime = tick.DateTime; tickObject.MarketDataProvider = tick.MarketDataProvider; // Return updated object return(tickObject); }); }
/// <summary> /// Forwards Execution messages to Client to be sent to Server /// </summary> /// <param name="execution">Contains Order Execution information</param> public void SendExecution(Execution execution) { try { // Process request only if the Client is working if (_tradeManagerClient.IsConnected()) { if (Logger.IsDebugEnabled) { Logger.Debug("Execution received: " + execution, _type.FullName, "SendExecution"); } // Send Execution to Disruptor _messagePublisher.PublishEvent((messageQueueObject, sequenceNo) => { byte[] messageBytes = Encoding.UTF8.GetBytes(execution.DataToPublish()); // Initialize Parameter messageQueueObject.Message = new byte[messageBytes.Length]; // Copy information messageBytes.CopyTo(messageQueueObject.Message, 0); // Return updated object return(messageQueueObject); }); } else { if (Logger.IsInfoEnabled) { Logger.Info("Execution not sent as Client is not connected", _type.FullName, "SendExecution"); } } } catch (Exception exception) { Logger.Error(exception, _type.FullName, "SendExecution"); } }
/// <summary> /// Publish an event to the <see cref="RingBuffer"/> /// </summary> /// <param name="eventTranslator">the translator function that will load data into the event.</param> public void PublishEvent(Func <T, long, T> eventTranslator) { _eventPublisher.PublishEvent(eventTranslator); }
/// <summary> /// Reading Data From ReadMarketData class. /// </summary> /// <param name="request"></param> public virtual void ReadData(BarDataRequest request) { try { IEnumerable <Bar> barlist = _readMarketData.ReadBars(_startDate, _endDate, _providerName, request); #region Send Required Info foreach (var bar in barlist) { // Update time DateTime time = bar.DateTime.AddMinutes(-1); for (int i = 0; i < 4; i++) { //Create Object to be disptched MarketDataObject marketDataObjectTick = new MarketDataObject(); // Create a new tick object Tick tick = new Tick(bar.Security, MarketDataProvider.SimulatedExchange) { // Add Last Price to new Tick instance LastPrice = GetRequiredPrice(i, bar), // Add Size LastSize = 100, // Set updated time DateTime = time.AddSeconds((i + 1) * 14) }; // Add Values to the object to be dispatched marketDataObjectTick.IsTick = true; marketDataObjectTick.Tick = tick; // Raise event to notify listeners _publisher.PublishEvent((entry, sequenceNo) => { entry.IsTick = marketDataObjectTick.IsTick; entry.Tick = marketDataObjectTick.Tick; return(entry); }); //if (TickFired != null) //{ // TickFired.Invoke(tick); //} } //Create Object to be disptched MarketDataObject marketDataObjectBar = new MarketDataObject(); marketDataObjectBar.Bar = bar; _publisher.PublishEvent((entry, sequenceNo) => { entry.Bar = marketDataObjectBar.Bar; return(entry); }); //if (BarFired != null) //{ // BarFired.Invoke(bar, request.Id); //} } #endregion //EventSystem.Publish<string>("DataCompleted," + request.Security.Symbol); } catch (Exception exception) { Logger.Error(exception, _type.FullName, "ReadData"); } }
public void PublishEvent(IEventTranslator <T> translator) { _eventPublisher.PublishEvent(translator.Translate); }
public async Task DemonstrateDisruptor( [Values(1, 2, 4)] int numberOfDeserializers, [Values(1024, 512)] int ringSize, [Values(10, 80)] int maxNumberOfItemsPerList, [Values("sleep")] string waitStrategyName, [Values("multi-low-contention")] string claimStrategyName ) { var listsPerRequest = 5; var numberOfTodoLists = 1500; var numberOfUpdates = 1500; var waitStrategies = new Dictionary <string, IWaitStrategy>() { { "busy", new BusySpinWaitStrategy() }, { "block", new BlockingWaitStrategy() }, { "yield", new YieldingWaitStrategy() }, { "sleep", new SleepingWaitStrategy() }, }; var claimStrategies = new Dictionary <string, IClaimStrategy>() { { "single", new SingleThreadedClaimStrategy(ringSize) }, { "multi", new MultiThreadedClaimStrategy(ringSize) }, { "multi-low-contention", new MultiThreadedLowContentionClaimStrategy(ringSize) }, }; var disruptor = new Disruptor <EventType>( () => new EventType(), claimStrategies[claimStrategyName], waitStrategies[waitStrategyName], TaskScheduler.Default ); var ringBuffer = disruptor.RingBuffer; var deserialize = GetDeserializers(numberOfDeserializers); var groupIntoRequests = GetRequestBuilders(listsPerRequest); disruptor.HandleEventsWith(deserialize) .Then(groupIntoRequests); // Since the Request Senders are AsyncEventProcessors instead of EventHandlers(synchronous) // We have to manually create a sequence barrier and pass it in instead of just calling .Then() again. var barrierUntilRequestsAreGrouped = disruptor.After(groupIntoRequests).AsSequenceBarrier(); var sendRequests = GetRequestSenders(ringBuffer, barrierUntilRequestsAreGrouped, RequestSenderMode.Callback); disruptor.HandleEventsWith(sendRequests); var writeLog = GetFinalLoggingEventHandler(); disruptor.After(sendRequests) .Then(writeLog); var configuredRingBuffer = disruptor.Start(); // There is a bug in the Disruptor code that prevents custom EventProcessors from running automatically // so we start them manually. If they were already started, and we try to start them again, // it would throw an exception here. foreach (var requestSender in sendRequests) { AsyncExtensions.FireAndForgetLongRunning(() => requestSender.Run(), (ex) => Assert.Fail(ex.StackTrace)); } var eventPublisher = new EventPublisher <EventType>(configuredRingBuffer); var messages = FakeDataGenerator.Generate(numberOfTodoLists, numberOfUpdates, maxNumberOfItemsPerList); var bytesThroughput = messages.Sum(x => (long)x.ContentJson.Length * 2); var megabytesThroughput = (double)bytesThroughput / 1000000; System.GC.Collect(); await Task.Delay(new TimeSpan(0, 0, 0, 0, 100)); var timer = new Stopwatch(); timer.Start(); for (var i = 0; i < messages.Length; i++) { // PublishEvent will block if there is no space avaliable on the ring buffer. eventPublisher.PublishEvent((@event, sequence) => { @event.IncomingMessage = messages[i]; return(@event); }); } // Shutdown will block until the ring buffer is empty. disruptor.Shutdown(); timer.Stop(); // Uncomment this to show a concise version of the requests that would have been sent. //Console.WriteLine(string.Join("\n", _resultLog)); var elapsedSeconds = (float)timer.ElapsedMilliseconds / 1000; var rateMegabytesPerSecond = (int)Math.Round((float)megabytesThroughput / elapsedSeconds); var strategy = $"{nameof(numberOfDeserializers)}: {numberOfDeserializers}, " + $"{nameof(ringSize)}: {ringSize}, " + $"{nameof(maxNumberOfItemsPerList)}: {maxNumberOfItemsPerList}, "; Console.WriteLine(); Console.WriteLine("Took: " + timer.ElapsedMilliseconds + " ms to process " + numberOfUpdates + " updates "); Console.WriteLine("at a rate of " + rateMegabytesPerSecond + " megabytes per second "); Console.WriteLine(); _ratings.Add(new Tuple <int, string>(rateMegabytesPerSecond, strategy)); }
/// <summary> /// Reading Data From ReadMarketData class. /// </summary> /// <param name="request"></param> public virtual void ReadData(BarDataRequest request) { try { IEnumerable <Bar> barlist = _readMarketData.ReadBars(_startDate, _endDate, _providerName, request); #region Send Required Info foreach (var bar in barlist) { // Update time DateTime time = bar.DateTime.AddMinutes(-1); for (int i = 0; i < 4; i++) { // Raise event to notify listeners _publisher.PublishEvent((entry, sequenceNo) => { // Update Security value entry.Tick.Security = new Security() { Symbol = bar.Security.Symbol }; // Update Market Data Provider value entry.Tick.MarketDataProvider = MarketDataProvider.SimulatedExchange; // Update Last Price Value entry.Tick.LastPrice = GetRequiredPrice(i, bar); // Update Size entry.Tick.LastSize = 100; // Set updated time entry.Tick.DateTime = time.AddSeconds((i + 1) * 14); entry.IsTick = true; return(entry); }); } // Raise event to notify listeners _publisher.PublishEvent((entry, sequenceNo) => { entry.Bar.Open = bar.Open; entry.Bar.High = bar.High; entry.Bar.Low = bar.Low; entry.Bar.Close = bar.Close; entry.Bar.RequestId = bar.RequestId; entry.Bar.DateTime = bar.DateTime; entry.Bar.MarketDataProvider = MarketDataProvider.SimulatedExchange; entry.Bar.Security = new Security() { Symbol = bar.Security.Symbol }; return(entry); }); } #endregion } catch (Exception exception) { _classLogger.Error(exception, _type.FullName, "ReadData - BarDataRequest"); } }