2021-09-27 12:42:46 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Xunit;
|
|
|
|
using static System.Threading.Tasks.Task;
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
namespace Wabbajack.RateLimiter.Test;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public class RateLimiter
|
|
|
|
{
|
|
|
|
//[Fact]
|
|
|
|
public async Task BasicTaskTests()
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
var rateLimiter = new Resource<int>("Test Resource", 2);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var current = 0;
|
|
|
|
var max = 0;
|
|
|
|
object lockObj = new();
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
void SetMax(object o, ref int i, ref int max1, int add)
|
|
|
|
{
|
|
|
|
lock (o)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
i += add;
|
|
|
|
max1 = Math.Max(i, max1);
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
2021-10-23 16:51:17 +00:00
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
await Parallel.ForEachAsync(Enumerable.Range(0, 100),
|
|
|
|
new ParallelOptions {MaxDegreeOfParallelism = 10},
|
|
|
|
async (x, token) =>
|
|
|
|
{
|
|
|
|
using var job = await rateLimiter.Begin("Incrementing", 1, CancellationToken.None);
|
|
|
|
SetMax(lockObj, ref current, ref max, 1);
|
|
|
|
await Delay(10, token);
|
|
|
|
SetMax(lockObj, ref current, ref max, -1);
|
|
|
|
});
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
Assert.Equal(2, max);
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
//[Fact]
|
|
|
|
public async Task TestBasicThroughput()
|
|
|
|
{
|
|
|
|
var rateLimiter = new Resource<int>("Test Resource", 1, 1024 * 1024);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
using var job = await rateLimiter.Begin("Transferring", 1024 * 1024 * 5 / 2, CancellationToken.None);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var sw = Stopwatch.StartNew();
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var report = rateLimiter.StatusReport;
|
|
|
|
Assert.Equal(0, report.Transferred);
|
|
|
|
foreach (var x in Enumerable.Range(0, 5)) await job.Report(1024 * 1024 / 2, CancellationToken.None);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var elapsed = sw.Elapsed;
|
|
|
|
Assert.True(elapsed > TimeSpan.FromSeconds(1));
|
|
|
|
Assert.True(elapsed < TimeSpan.FromSeconds(3));
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
report = rateLimiter.StatusReport;
|
|
|
|
Assert.Equal(1024 * 1024 * 5 / 2, report.Transferred);
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
//[Fact]
|
|
|
|
public async Task TestParallelThroughput()
|
|
|
|
{
|
|
|
|
var rateLimiter = new Resource<int>("Test Resource", 2, 1024 * 1024);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var sw = Stopwatch.StartNew();
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var tasks = new List<Task>();
|
|
|
|
for (var i = 0; i < 4; i++)
|
|
|
|
tasks.Add(Run(async () =>
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
using var job = await rateLimiter.Begin("Transferring", 1024 * 1024 / 10 * 5, CancellationToken.None);
|
|
|
|
for (var x = 0; x < 5; x++) await job.Report(1024 * 1024 / 10, CancellationToken.None);
|
|
|
|
}));
|
|
|
|
|
|
|
|
await WhenAll(tasks.ToArray());
|
|
|
|
var elapsed = sw.Elapsed;
|
|
|
|
Assert.True(elapsed > TimeSpan.FromSeconds(1));
|
|
|
|
Assert.True(elapsed < TimeSpan.FromSeconds(3));
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
//[Fact]
|
|
|
|
public async Task TestParallelThroughputWithLimitedTasks()
|
|
|
|
{
|
|
|
|
var rateLimiter = new Resource<int>("Test Resource", 1, 1024 * 1024 * 4);
|
|
|
|
;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var sw = Stopwatch.StartNew();
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
var tasks = new List<Task>();
|
|
|
|
for (var i = 0; i < 4; i++)
|
|
|
|
tasks.Add(Run(async () =>
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
using var job = await rateLimiter.Begin("Transferring", 1024 * 1024 / 10 * 5, CancellationToken.None);
|
|
|
|
for (var x = 0; x < 5; x++) await job.Report(1024 * 1024 / 10, CancellationToken.None);
|
|
|
|
}));
|
|
|
|
|
|
|
|
await WhenAll(tasks.ToArray());
|
|
|
|
var elapsed = sw.Elapsed;
|
|
|
|
Assert.True(elapsed > TimeSpan.FromSeconds(0.5));
|
|
|
|
Assert.True(elapsed < TimeSpan.FromSeconds(1.5));
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
}
|