Пример #1
0
            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);
                    }
                }
            }
Пример #2
0
        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;
         }
     }
 }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
            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;
                    }
                }
            }
Пример #6
0
 public bool TryGetValue(string key, out ThrottleEntry entry)
 {
     return _throttleStore.TryGetValue(key, out entry);
 }