using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace CryptoExchange.Net.RateLimiter
{
///
/// Limits the amount of requests per time period to a certain limit, counts the total amount of requests.
///
public class RateLimiterTotal: IRateLimiter
{
internal List history = new List();
private int limit;
private TimeSpan perTimePeriod;
private object requestLock = new object();
///
/// Create a new RateLimiterTotal. This rate limiter limits the amount of requests per time period to a certain limit, counts the total amount of requests.
///
/// The amount to limit to
/// The time period over which the limit counts
public RateLimiterTotal(int limit, TimeSpan perTimePeriod)
{
this.limit = limit;
this.perTimePeriod = perTimePeriod;
}
public double LimitRequest(string url)
{
var sw = Stopwatch.StartNew();
lock (requestLock)
{
sw.Stop();
double waitTime = 0;
var checkTime = DateTime.UtcNow;
history.RemoveAll(d => d < checkTime - perTimePeriod);
if (history.Count >= limit)
{
waitTime = (history.First() - (checkTime - perTimePeriod)).TotalMilliseconds;
if (waitTime > 0)
{
Thread.Sleep(Convert.ToInt32(waitTime));
waitTime += sw.ElapsedMilliseconds;
}
}
history.Add(DateTime.UtcNow);
history.Sort();
return waitTime;
}
}
}
}