private void DeleteEmptyRequestsData(IClientIdentifier identifier) { if (_requests.ContainsKey(identifier) && _requests[identifier].Count == 0) { _requests.Remove(identifier); } }
private void UpdateRequestCount(IClientIdentifier identifier) { var expiryDate = _systemClock.UtcNow.Subtract(_configuration.RefreshRate); _requestStore.DeleteRequestsOlderThan(identifier, expiryDate); _requestStore.AddRequest(identifier, _systemClock.UtcNow); }
public int NumberOfRequestsFor(IClientIdentifier identifier) { lock (_syncObject) { return(_requests.ContainsKey(identifier) ? _requests[identifier].Count : 0); } }
public int RequestsRemaining(IClientIdentifier identifier) { UpdateRequestCount(identifier); var numberOfRequests = GetNumberOfRequests(identifier); var remaining = _configuration.Limit - numberOfRequests; return(remaining); }
public void DeleteRequestsOlderThan(IClientIdentifier identifier, DateTime expiryDate) { lock (_syncObject) { if (_requests.ContainsKey(identifier)) { while (HasExpired(identifier, expiryDate)) { _requests[identifier].Dequeue(); } } DeleteEmptyRequestsData(identifier); } }
public void AddRequest(IClientIdentifier identifier, DateTime dateTime) { lock (_syncObject) { if (!_requests.ContainsKey(identifier)) { _requests.Add(identifier, new Queue <DateTime>(_maxNumberOfRequests)); } if (_requests[identifier].Count == _maxNumberOfRequests) { _requests[identifier].Dequeue(); } _requests[identifier].Enqueue(dateTime); } }
private bool HasExpired(IClientIdentifier identifier, DateTime expiryDate) { return(_requests[identifier].Count > 0 && _requests[identifier].Peek() < expiryDate); }
private int GetNumberOfRequests(IClientIdentifier identifier) { return(_requestStore.NumberOfRequestsFor(identifier)); }
public async Task <RateLimitCacheEntry> CanAccessResource(string policyId, int limitPerHour, IClientIdentifier clientId) { var key = $"{policyId}:{clientId.IdentifierString}"; var existing = await _cache.GetJsonAsync <RateLimitCacheEntry>(key) ?? new RateLimitCacheEntry { Remaining = limitPerHour, Resets = DateTime.UtcNow + TimeSpan.FromHours(1), }; var updated = new RateLimitCacheEntry { Remaining = existing.Remaining - 1, Resets = existing.Resets, }; await _cache.SetJsonAsync(key, updated, new DistributedCacheEntryOptions { AbsoluteExpiration = new DateTimeOffset(updated.Resets, TimeSpan.Zero), }); return(existing); }