add CountParallelSignals performance test.

This commit is contained in:
Sebastian Burckhardt 2021-01-26 12:59:11 -08:00
Родитель 5b825a265f
Коммит e4f32a595e
1 изменённых файлов: 69 добавлений и 1 удалений

Просмотреть файл

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
@ -98,7 +99,7 @@
if (response.EntityExists
&& response.EntityState.CurrentValue == numberSignals)
{
return new OkObjectResult($"received {numberSignals} signals in {(DateTime.UtcNow-startTime).TotalSeconds:F1}s.\n");
return new OkObjectResult($"received {numberSignals} signals in {(response.EntityState.LastModified - startTime).TotalSeconds:F1}s.\n");
}
await Task.Delay(TimeSpan.FromSeconds(2));
@ -112,6 +113,73 @@
}
}
[FunctionName(nameof(CountParallelSignals))]
public static async Task<IActionResult> CountParallelSignals(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = nameof(CountParallelSignals))] HttpRequest req,
[DurableClient] IDurableClient client)
{
try
{
// input is of the form "nnn,mmm"
// nnn - number of signals to send
// mmm - number of entities to distribute the signals over
string input = await new StreamReader(req.Body).ReadToEndAsync();
int commaPosition = input.IndexOf(',');
int numberSignals = int.Parse(input.Substring(0, commaPosition));
int numberEntities = int.Parse(input.Substring(commaPosition + 1));
var entityPrefix = Guid.NewGuid().ToString("N");
EntityId MakeEntityId(int i) => new EntityId("Counter", $"{entityPrefix}-{i:D8}");
DateTime startTime = DateTime.UtcNow;
// send the specified number of signals to the entity
// for max throughput we do this in parallel and without waiting
Parallel.For(0, numberSignals, (i) =>
{
var asyncTask = client.SignalEntityAsync(MakeEntityId(i % numberEntities), "add", 1);
});
// poll the entities until the expected count is reached
async Task<double?> WaitForCount(int i)
{
var random = new Random();
while ((DateTime.UtcNow - startTime) < TimeSpan.FromMinutes(5))
{
var response = await client.ReadEntityStateAsync<Counter>(MakeEntityId(i));
if (response.EntityExists
&& response.EntityState.CurrentValue == numberSignals / numberEntities)
{
return (response.EntityState.LastModified - startTime).TotalSeconds;
}
await Task.Delay(TimeSpan.FromSeconds(2 + random.NextDouble()));
}
return null;
};
var waitTasks = Enumerable.Range(0, numberEntities).Select(i => WaitForCount(i)).ToList();
await Task.WhenAll(waitTasks);
var results = waitTasks.Select(t => t.Result);
if (results.Any(result => result == null))
{
return new OkObjectResult($"timed out after {(DateTime.UtcNow - startTime)}.\n");
}
return new OkObjectResult($"received {numberSignals} signals on {numberEntities} entities in {results.Max():F1}s.\n");
}
catch (Exception e)
{
return new OkObjectResult(e.ToString());
}
}
}
public class Counter