public void Run(CancellationToken cancellationToken = default(CancellationToken)) { _capture = new MessageMetricCapture(_settings.MessageCount); IBusControl busControl = _transport.GetBusControl(ConfigureReceiveEndpoint); try { Console.WriteLine("Running Message Latency Benchmark"); TaskUtil.Await(() => RunBenchmark(busControl), cancellationToken); Console.WriteLine("Message Count: {0}", _settings.MessageCount); Console.WriteLine("Clients: {0}", _settings.Clients); Console.WriteLine("Durable: {0}", _settings.Durable); Console.WriteLine("Publisher Confirmation: {0}", _settings.PublisherConfirmation); Console.WriteLine("Payload Length: {0}", _payload?.Length ?? 0); Console.WriteLine("Prefetch Count: {0}", _settings.PrefetchCount); Console.WriteLine("Concurrency Limit: {0}", _settings.ConcurrencyLimit); Console.WriteLine("Total send duration: {0:g}", _sendDuration); Console.WriteLine("Send message rate: {0:F2} (msg/s)", _settings.MessageCount * 1000 / _sendDuration.TotalMilliseconds); Console.WriteLine("Total consume duration: {0:g}", _consumeDuration); Console.WriteLine("Consume message rate: {0:F2} (msg/s)", _settings.MessageCount * 1000 / _consumeDuration.TotalMilliseconds); Console.WriteLine("Concurrent Consumer Count: {0}", MessageLatencyConsumer.MaxConsumerCount); MessageMetric[] messageMetrics = _capture.GetMessageMetrics(); Console.WriteLine("Avg Ack Time: {0:F0}ms", messageMetrics.Average(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Min Ack Time: {0:F0}ms", messageMetrics.Min(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Max Ack Time: {0:F0}ms", messageMetrics.Max(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Med Ack Time: {0:F0}ms", messageMetrics.Median(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("95t Ack Time: {0:F0}ms", messageMetrics.Percentile(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Avg Consume Time: {0:F0}ms", messageMetrics.Average(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Min Consume Time: {0:F0}ms", messageMetrics.Min(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Max Consume Time: {0:F0}ms", messageMetrics.Max(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Med Consume Time: {0:F0}ms", messageMetrics.Median(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("95t Consume Time: {0:F0}ms", messageMetrics.Percentile(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine(); DrawResponseTimeGraph(messageMetrics, x => x.ConsumeLatency); } finally { busControl.Stop(); } }
public void Run(CancellationToken cancellationToken = default(CancellationToken)) { _capture = new MessageMetricCapture(_settings.MessageCount); var busControl = _transport.GetBusControl(ConfigureReceiveEndpoint); _client = new MessageRequestClient<RequestMessage, ResponseMessage>(busControl, _transport.TargetEndpointAddress, _settings.RequestTimeout); try { Console.WriteLine("Running Request Response Benchmark"); TaskUtil.Await(() => RunBenchmark(), cancellationToken); Console.WriteLine("Message Count: {0}", _settings.MessageCount); Console.WriteLine("Clients: {0}", _settings.Clients); Console.WriteLine("Durable: {0}", _settings.Durable); Console.WriteLine("Prefetch Count: {0}", _settings.PrefetchCount); Console.WriteLine("Concurrency Limit: {0}", _settings.ConcurrencyLimit); Console.WriteLine("Total consume duration: {0:g}", _consumeDuration); Console.WriteLine("Consume message rate: {0:F2} (msg/s)", _settings.MessageCount * 1000 / _consumeDuration.TotalMilliseconds); Console.WriteLine("Total request duration: {0:g}", _requestDuration); Console.WriteLine("Request rate: {0:F2} (msg/s)", _settings.MessageCount * 1000 / _requestDuration.TotalMilliseconds); Console.WriteLine("Concurrent Consumer Count: {0}", RequestConsumer.MaxConsumerCount); MessageMetric[] messageMetrics = _capture.GetMessageMetrics(); Console.WriteLine("Avg Request Time: {0:F0}ms", messageMetrics.Average(x => x.RequestLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Min Request Time: {0:F0}ms", messageMetrics.Min(x => x.RequestLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Max Request Time: {0:F0}ms", messageMetrics.Max(x => x.RequestLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Med Request Time: {0:F0}ms", messageMetrics.Median(x => x.RequestLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("95t Request Time: {0:F0}ms", messageMetrics.Percentile(x => x.RequestLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Avg Consume Time: {0:F0}ms", messageMetrics.Average(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Min Consume Time: {0:F0}ms", messageMetrics.Min(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Max Consume Time: {0:F0}ms", messageMetrics.Max(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Med Consume Time: {0:F0}ms", messageMetrics.Median(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("95t Consume Time: {0:F0}ms", messageMetrics.Percentile(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine(); Console.WriteLine("Request duration distribution"); DrawResponseTimeGraph(messageMetrics, x => x.RequestLatency); } finally { busControl.Stop(); } }
public static async Task RunTest(JustSayingBenchmark options) { Console.WriteLine("Running benchmark with message count of {0}", options.MessageCount); var capture = new MessageMetricCapture(options.MessageCount); var services = new ServiceCollection() .AddSingleton <IReportConsumerMetric>(capture) .AddLogging(lg => lg.AddSerilog()); RegisterJustSaying(services); var provider = services.BuildServiceProvider(); var publisher = provider.GetService <IMessagePublisher>(); using (Operation.Time("Executing startup work")) { await publisher.StartAsync(CancellationToken.None); var bus = provider.GetService <IMessagingBus>(); await bus.StartAsync(CancellationToken.None); } Console.WriteLine("Completed startup, beginning benchmark"); var watch = new Stopwatch(); var taskBatches = Enumerable.Range(0, options.MessageCount).Batch(20) .Select(async batch => { var messageTasks = batch.Select(id => new BenchmarkMessage(watch.Elapsed, id)) .Select(async x => await capture.Sent(x.Id, publisher.PublishAsync(x))); await Task.WhenAll(messageTasks); }).ToList(); var batchId = 1; var batchCount = taskBatches.Count; foreach (var taskBatch in taskBatches) { using (Operation.Time("Sending batch id {BatchId} of {BatchCount}", batchId, batchCount)) { await taskBatch; } } Log.Information("Waiting for sends to complete..."); await capture.SendCompleted; Log.Information("Waiting for consumes to complete..."); await capture.ConsumeCompleted; Log.Information("Sends and Consumes completed!"); var messageMetrics = capture.GetMessageMetrics(); Console.WriteLine("Avg Ack Time: {0:F0}ms", messageMetrics.Average(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Min Ack Time: {0:F0}ms", messageMetrics.Min(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Max Ack Time: {0:F0}ms", messageMetrics.Max(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Med Ack Time: {0:F0}ms", messageMetrics.Median(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("95t Ack Time: {0:F0}ms", messageMetrics.Percentile(x => x.AckLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Avg Consume Time: {0:F0}ms", messageMetrics.Average(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Min Consume Time: {0:F0}ms", messageMetrics.Min(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Max Consume Time: {0:F0}ms", messageMetrics.Max(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("Med Consume Time: {0:F0}ms", messageMetrics.Median(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); Console.WriteLine("95t Consume Time: {0:F0}ms", messageMetrics.Percentile(x => x.ConsumeLatency) * 1000 / Stopwatch.Frequency); DrawResponseTimeGraph(messageMetrics, m => m.ConsumeLatency); }