This repository was archived by the owner on Nov 1, 2023. It is now read-only.
Ensuring thread safety
In order to ensure thread safety, the ThrottleCounter
object is now of type struct
and all CRUD operations are done with locking.
static readonly object _processLocker = new object();
private ThrottleCounter ProcessRequest(
ThrottlePolicy throttlePolicy,
RequestIndentity throttleEntry,
TimeSpan timeSpan,
RateLimitPeriod period, out string id)
{
var throttleCounter = new ThrottleCounter();
throttleCounter.Timestamp = DateTime.UtcNow;
throttleCounter.TotalRequests = 1;
id = "throttle";
//computed request unique id from IP, client key, url and period
//get the hash value of the computed id
var hashId = ComputeHash(id);
//serial reads and writes
lock (_processLocker)
{
var entry = Repository.FirstOrDefault(hashId);
if (entry.HasValue)
{
//entry has not expired
if (entry.Value.Timestamp + timeSpan >= DateTime.UtcNow)
{
//increment request count
var totalRequests = entry.Value.TotalRequests + 1;
//deep copy
throttleCounter = new ThrottleCounter
{
Timestamp = entry.Value.Timestamp,
TotalRequests = totalRequests
};
}
}
//stores: id (string) - timestamp (datetime) - total (long)
Repository.Save(hashId, throttleCounter, timeSpan);
}
return throttleCounter;
}