using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace CryptoExchange.Net.RateLimiter
{
///
/// Limits the amount of requests per time period to a certain limit, counts the request per endpoint.
///
public class RateLimiterPerEndpoint: IRateLimiter
{
internal Dictionary history = new Dictionary();
private int limitPerEndpoint;
private TimeSpan perTimePeriod;
private object historyLock = new object();
///
/// Create a new RateLimiterPerEndpoint. This rate limiter limits the amount of requests per time period to a certain limit, counts the request per endpoint.
///
/// The amount to limit to
/// The time period over which the limit counts
public RateLimiterPerEndpoint(int limitPerEndpoint, TimeSpan perTimePeriod)
{
this.limitPerEndpoint = limitPerEndpoint;
this.perTimePeriod = perTimePeriod;
}
public double LimitRequest(string url)
{
double waitTime;
RateLimitObject rlo;
lock (historyLock)
{
if (history.ContainsKey(url))
rlo = history[url];
else
{
rlo = new RateLimitObject();
history.Add(url, rlo);
}
}
var sw = Stopwatch.StartNew();
lock (rlo.LockObject)
{
sw.Stop();
waitTime = rlo.GetWaitTime(DateTime.UtcNow, limitPerEndpoint, perTimePeriod);
if (waitTime != 0)
{
Thread.Sleep(Convert.ToInt32(waitTime));
waitTime += sw.ElapsedMilliseconds;
}
rlo.Add(DateTime.UtcNow);
}
return waitTime;
}
}
}