public bool Acquire(int channelKey) { lock (this.pendingMessages) { if (!this.pendingMessages.ContainsKey(channelKey)) { this.pendingMessages.Add(channelKey, new ThrottleEntry()); } ThrottleEntry entry = this.pendingMessages[channelKey]; if (entry.Count < this.maxPendingMessagesPerChannel) { entry.Count++; if (TD.PendingMessagesPerChannelRatioIsEnabled()) { TD.PendingMessagesPerChannelRatio(entry.Count, this.maxPendingMessagesPerChannel); } return(true); } else { if (TD.MaxPendingMessagesPerChannelExceededIsEnabled()) { if (!entry.WarningIssued) { TD.MaxPendingMessagesPerChannelExceeded(this.maxPendingMessagesPerChannel); entry.WarningIssued = true; } } return(false); } } }
protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var identifier = GetUserIdentifier(request); if (string.IsNullOrEmpty(identifier)) { return(CreateResponse(request, HttpStatusCode.Forbidden, "Could not identify client.")); } var maxRequests = _maxRequestsForUserIdentifier(identifier); ThrottleEntry entry = null; if (_store.TryGetValue(identifier, out entry)) { if (entry.PeriodStart + _period < DateTime.UtcNow) { _store.Rollover(identifier); } } _store.IncrementRequests(identifier); if (!_store.TryGetValue(identifier, out entry)) { return(CreateResponse(request, HttpStatusCode.Forbidden, "Could not identify client.")); } Task <HttpResponseMessage> response = null; if (entry.Requests > maxRequests) { response = CreateResponse(request, HttpStatusCode.Conflict, _message); } else { response = base.SendAsync(request, cancellationToken); } return(response.ContinueWith(task => { var remaining = maxRequests - entry.Requests; if (remaining < 0) { remaining = 0; } var httpResponse = task.Result; httpResponse.Headers.Add("RateLimit-Limit", maxRequests.ToString()); httpResponse.Headers.Add("RateLimit-Remaining", remaining.ToString()); return httpResponse; })); }
public void Release(int channelKey) { lock (this.pendingMessages) { ThrottleEntry entry = this.pendingMessages[channelKey]; entry.Count--; if (entry.Count == 0) { this.pendingMessages.Remove(channelKey); } else if (entry.Count < this.warningRestoreLimit) { entry.WarningIssued = false; } } }
public async Task <bool> ThrottleOrIncrement(string key) { await _table.CreateIfNotExistsAsync(); var query = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "any"), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, key) ); var exQuery = new TableQuery <ThrottleEntry>().Where(query); var entry = await QueryHelper.Get(_table, exQuery); if (entry == null) { // Create entry = new ThrottleEntry { PartitionKey = "any", RowKey = key, Count = 1 }; await _table.ExecuteAsync(TableOperation.Insert(entry)); _log.Info($"Throttle count for ${key} initialized to {entry.Count}"); return(false); } else { if (entry.Count >= ThrottleLimit) { _log.Info($"Throttle count for ${key} has been reached, throttled"); return(true); } else { entry.Count++; await _table.ExecuteAsync(TableOperation.Replace(entry)); _log.Info($"Throttle count for ${key} increased to {entry.Count}"); return(false); } } }
public void Release(int channelKey) { lock (this.pendingMessages) { ThrottleEntry entry = this.pendingMessages[channelKey]; Fx.Assert(entry.Count > 0, "The pending message throttle was released too many times"); entry.Count--; if (TD.PendingMessagesPerChannelRatioIsEnabled()) { TD.PendingMessagesPerChannelRatio(entry.Count, this.maxPendingMessagesPerChannel); } if (entry.Count == 0) { this.pendingMessages.Remove(channelKey); } else if (entry.Count < this.warningRestoreLimit) { entry.WarningIssued = false; } } }
public bool TryGetValue(string key, out ThrottleEntry entry) { return _throttleStore.TryGetValue(key, out entry); }