Пример #1
0
        private DbRateLimiterConfig GetDbConfig(RateLimiterConfig config)
        {
            var dbConfig = new DbRateLimiterConfig
            {
                RequestTimeout = config.RequestTimeout
            };

            switch (config.RateLimiterType)
            {
            case RateLimiterType.Burst:
                dbConfig.MaxTokens          = config.IntervalCount;
                dbConfig.OperationsInterval = config.IntervalRange;
                break;

            case RateLimiterType.Interval:
                dbConfig.MaxTokens          = 1;
                dbConfig.OperationsInterval = TimeSpanDivision(config.IntervalRange, config.IntervalCount);
                break;

            default:
                throw new ArgumentOutOfRangeException($"Unknown RateLimiter type of {config.RateLimiterType:G}");
            }

            dbConfig.StorageKey = GetStorageKey(
                config.Key,
                dbConfig.MaxTokens,
                dbConfig.OperationsInterval.Milliseconds);

            return(dbConfig);
        }
Пример #2
0
        private DateTimeOffset TryAllocateToken(DbRateLimiterConfig config)
        {
            var startDate = DateTimeOffset.UtcNow;

            for (var current = startDate;
                 current - startDate < config.RequestTimeout;
                 current = DateTimeOffset.UtcNow)
            {
                var expirationDate = current.Subtract(config.OperationsInterval);
                var tokenCount     = _repo.GetTokenCount(config.StorageKey, expirationDate);
                if (tokenCount >= config.MaxTokens)
                {
                    //TODO: dynamic backoff sleep or retry class (move to top)
                    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
                    continue;
                }

                _repo.AllocateToken(config);
                return(current);
            }
            throw new RateLimitTimeoutException($"Could not get a token in '{config.RequestTimeout.Seconds}' seconds");
        }