private RateLimitProcessor <SimulationRequest> GetLeakyBucketProcessor(string storageType, int limitNumber)
        {
            IRateLimitStorage storage = memoryStorage;

            if (storageType == "redis")
            {
                storage = redisStorage;
            }

            var leakyBucketRules = new LeakyBucketRateLimitRule <SimulationRequest>[]
            {
                new LeakyBucketRateLimitRule <SimulationRequest>(limitNumber, 100, TimeSpan.FromSeconds(1))
                {
                    Id            = Guid.NewGuid().ToString(),
                    LockSeconds   = 1,
                    ExtractTarget = (request) =>
                    {
                        return(request.RequestResource);
                    },
                    CheckRuleMatching = (request) =>
                    {
                        return(true);
                    },
                }
            };

            return(new RateLimitProcessor <SimulationRequest> .Builder()
                   .WithAlgorithm(new LeakyBucketAlgorithm <SimulationRequest>(leakyBucketRules))
                   .WithStorage(storage)
                   .WithError(new RateLimitError()
            {
                Code = 429,
            })
                   .Build());
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="target"></param>
        /// <param name="storage"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override async Task <bool> CheckSingleRuleAsync(string target, IRateLimitStorage storage, RateLimitRule <TRequest> rule)
        {
            var currentRule = rule as SlidingWindowRateLimitRule <TRequest>;
            var result      = await storage.SlidingWindowIncrementAsync(target, 1, currentRule.StatWindow, currentRule.StatPeriod, currentRule.PeriodNumber, currentRule.LimitNumber, currentRule.LockSeconds);

            Debug.WriteLine("check result:" + result.Item1 + "," + result.Item2);
            return(result.Item1);
        }
示例#3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="target"></param>
        /// <param name="storage"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override async Task <bool> CheckSingleRuleAsync(string target, IRateLimitStorage storage, RateLimitRule <TRequest> rule)
        {
            var currentRule = rule as TokenBucketRateLimitRule <TRequest>;
            var result      = await storage.TokenBucketDecrementAsync(target, 1, currentRule.Capacity, (int)currentRule.InflowUnit.TotalMilliseconds, currentRule.InflowQuantityPerUnit, currentRule.LockSeconds);

            Debug.WriteLine("check result:" + result.Item1 + "," + result.Item2);
            return(result.Item1);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="target"></param>
        /// <param name="storage"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override async Task <bool> CheckSingleRuleAsync(string target, IRateLimitStorage storage, RateLimitRule <TRequest> rule)
        {
            var currentRule    = rule as FixedWindowRateLimitRule <TRequest>;
            var countAmount    = 1;
            var expireTimeSpan = currentRule.StatWindow;
            var result         = await storage.FixedWindowIncrementAsync(target, countAmount, expireTimeSpan, currentRule.LimitNumber, rule.LockSeconds);

            return(result.Item1);
        }
示例#5
0
        /// <summary>
        /// check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="storage"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override bool CheckSingleRule(string target, IRateLimitStorage storage, RateLimitRule <TRequest> rule)
        {
            var currentRule = rule as LeakyBucketRateLimitRule <TRequest>;

            var result = storage.LeakyBucketIncrement(target, 1, currentRule.Capacity, (int)currentRule.OutflowUnit.TotalMilliseconds, currentRule.OutflowQuantityPerUnit, currentRule.LockSeconds);

            Debug.WriteLine("check result:" + result.Item1 + "," + result.Item2);
            return(result.Item1);
        }
示例#6
0
            /// <summary>
            /// Build a instance of RateLimitProcessor with some configurations
            /// </summary>
            /// <returns></returns>
            public RateLimitProcessor <TRequest> Build()
            {
                if (_storage == null)
                {
                    _storage = new InProcessMemoryStorage();
                }

                if (_algorithm == null)
                {
                    throw new ArgumentNullException("the algorithm can not be null.");
                }

                if (_error == null)
                {
                    _error = new RateLimitError();
                }

                return(new RateLimitProcessor <TRequest>(_storage, _algorithm, _error));
            }
        /// <summary>
        /// check a request for rate limit
        /// </summary>
        /// <param name="request">a request</param>
        /// <param name="storage">a instance of IRateLimitStorage</param>
        /// <returns>the list of check result</returns>
        public List <RateLimitCheckResult <TRequest> > Check(TRequest request, IRateLimitStorage storage)
        {
            List <RateLimitCheckResult <TRequest> > results = new List <RateLimitCheckResult <TRequest> >();

            if (_updatable)
            {
                try
                {
                    _lock.EnterReadLock();
                    CheckAllRules(request, storage, results);
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
            else
            {
                CheckAllRules(request, storage, results);
            }

            return(results);
        }
        private void CheckAllRules(TRequest request, IRateLimitStorage storage, List <RateLimitCheckResult <TRequest> > results)
        {
            foreach (var rule in _rules)
            {
                if (rule.CheckRuleMatching(request))
                {
                    var target = rule.ExtractTarget(request);
                    if (string.IsNullOrWhiteSpace(target))
                    {
                        throw new NotSupportedException("不支持Target为空");
                    }

                    target = string.Concat(rule.Id, "-", target); // target for rule
                    bool result = CheckSingleRule(target, storage, rule);
                    results.Add(new RateLimitCheckResult <TRequest>()
                    {
                        Rule    = rule,
                        Target  = target,
                        IsLimit = result
                    });
                }
            }
        }
        private RateLimitProcessor <SimulationRequest> GetFixedWindowProcessor(string storageType, int limitNumber)
        {
            IRateLimitStorage storage = memoryStorage;

            if (storageType == "redis")
            {
                storage = redisStorage;
            }

            var fixedWindowRules = new FixedWindowRateLimitRule <SimulationRequest>[]
            {
                new FixedWindowRateLimitRule <SimulationRequest>()
                {
                    Id            = Guid.NewGuid().ToString(),
                    StatWindow    = TimeSpan.FromSeconds(1),
                    LimitNumber   = limitNumber,
                    ExtractTarget = (request) =>
                    {
                        return(request.RequestResource);
                    },
                    CheckRuleMatching = (request) =>
                    {
                        return(true);
                    },
                }
            };

            return(new RateLimitProcessor <SimulationRequest> .Builder()
                   .WithAlgorithm(new FixedWindowAlgorithm <SimulationRequest>(fixedWindowRules))
                   .WithStorage(storage)
                   .WithError(new RateLimitError()
            {
                Code = 429,
            })
                   .Build());
        }
示例#10
0
 /// <summary>
 /// Sets a instance of IRateLimitStorage
 /// </summary>
 /// <param name="storage"></param>
 /// <returns></returns>
 public Builder WithStorage(IRateLimitStorage storage)
 {
     _storage = storage;
     return(this);
 }
示例#11
0
 /// <summary>
 /// create a new instance
 /// </summary>
 /// <param name="storage"></param>
 /// <param name="algorithm"></param>
 /// <param name="error"></param>
 private RateLimitProcessor(IRateLimitStorage storage, IRateLimitAlgorithm <TRequest> algorithm, RateLimitError error)
 {
     _algorithm = algorithm;
     _storage   = storage;
     _error     = error;
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="target"></param>
 /// <param name="storage"></param>
 /// <param name="rule"></param>
 /// <returns></returns>
 protected abstract Task <bool> CheckSingleRuleAsync(string target, IRateLimitStorage storage, RateLimitRule <TRequest> rule);
 /// <summary>
 ///
 /// </summary>
 /// <param name="target"></param>
 /// <param name="storage"></param>
 /// <param name="rule"></param>
 /// <returns></returns>
 protected abstract bool CheckSingleRule(string target, IRateLimitStorage storage, RateLimitRule <TRequest> rule);
 public void GlobalSetup()
 {
     memoryStorage = new InProcessMemoryStorage();
     redisStorage  = new RedisStorage(StackExchange.Redis.ConnectionMultiplexer.Connect("127.0.0.1"));
 }