aspnetcore/benchmarks/Crankier/Runner.cs

105 lines
3.6 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Connections;
using Newtonsoft.Json;
namespace Microsoft.AspNetCore.SignalR.Crankier
{
public class Runner : IRunner
{
private readonly Agent _agent;
private readonly string _targetUrl;
private readonly int _numberOfWorkers;
private readonly int _numberOfConnections;
private readonly int _sendDurationSeconds;
private readonly HttpTransportType _transportType;
public Runner(Agent agent, string targetUrl, int numberOfWorkers, int numberOfConnections, int sendDurationInSeconds, HttpTransportType transportType)
{
_agent = agent;
_targetUrl = targetUrl;
_numberOfWorkers = numberOfWorkers;
_numberOfConnections = numberOfConnections;
_sendDurationSeconds = sendDurationInSeconds;
_transportType = transportType;
}
public async Task RunAsync()
{
_agent.Runner = this;
await _agent.StartWorkersAsync(_targetUrl, _numberOfWorkers, _transportType, _numberOfConnections);
// Begin writing worker status information
var writeStatusCts = new CancellationTokenSource();
var writeStatusTask = WriteConnectionStatusAsync(writeStatusCts.Token);
// Wait until all connections are connected
while (_agent.GetWorkerStatus().Aggregate(0, (state, status) => state + status.Value.ConnectedCount) <
_agent.TotalConnectionsRequested)
{
await Task.Delay(1000);
}
// Stay connected for the duration of the send phase
await Task.Delay(TimeSpan.FromSeconds(_sendDurationSeconds));
// Disconnect
await _agent.StopWorkersAsync();
// Stop writing worker status information
writeStatusCts.Cancel();
await writeStatusTask;
}
private Task WriteConnectionStatusAsync(CancellationToken cancellationToken)
{
return Task.Run(async () =>
{
var peakConnections = 0;
while (!cancellationToken.IsCancellationRequested)
{
var statusDictionary = _agent.GetWorkerStatus();
// Total things up
var status = new StatusInformation();
foreach (var value in statusDictionary.Values)
{
status = status.Add(value);
}
peakConnections = Math.Max(peakConnections, status.ConnectedCount);
status.PeakConnections = peakConnections;
Trace.WriteLine(JsonConvert.SerializeObject(status));
await Task.Delay(1000);
}
});
}
public Task PongWorkerAsync(int workerId, int value)
{
throw new NotImplementedException();
}
public Task LogAgentAsync(string format, params object[] arguments)
{
Trace.WriteLine(string.Format(format, arguments));
return Task.CompletedTask;
}
public Task LogWorkerAsync(int workerId, string format, params object[] arguments)
{
Trace.WriteLine(string.Format("({0}) {1}", workerId, string.Format(format, arguments)));
return Task.CompletedTask;
}
}
}