Пример #1
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="target"></param>
 /// <param name="rule"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 protected override async Task <RuleCheckResult> CheckSingleRuleAsync(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
 {
     return(await Task.FromResult(CheckSingleRule(target, rule, rateLimitAttrData)));
 }
Пример #2
0
        /// <summary>
        /// check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override RuleCheckResult CheckSingleRule(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as FixedWindowRule;
            var amount      = 1;

            #region local attribute

            if (rateLimitAttrData != null && rateLimitAttrData.FixedWindowLimitAttribute != null)
            {
                currentRule.LimitNumber             = rateLimitAttrData.FixedWindowLimitAttribute.LimitNumber;
                currentRule.StatWindow              = CommonUtils.Parse(rateLimitAttrData.FixedWindowLimitAttribute.Period);
                currentRule.RateLimitExceptionThrow = rateLimitAttrData.FixedWindowLimitAttribute.RateLimitExceptionThrow;
            }

            #endregion local attribute

            long expireTime = (long)currentRule.StatWindow.TotalMilliseconds;
            if (currentRule.StartTimeType == StartTimeType.FromNaturalPeriodBeign)
            {
                DateTimeOffset now = _timeProvider.GetCurrentUtcTime();
                expireTime = GetExpireTimeFromNaturalPeriodBeign(currentRule.StatWindow, now);
            }

            var ret = (long[])EvaluateScript(_fixedWindowIncrementLuaScript,
                                             new RedisKey[] { target },
                                             new RedisValue[] { amount, expireTime, currentRule.LimitNumber, currentRule.LockSeconds });
            return(new RuleCheckResult()
            {
                IsLimit = ret[0] == 0 ? false : true,
                Target = target,
                Count = ret[1],
                Rule = rule,
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }
Пример #3
0
        /// <summary>
        /// check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override RuleCheckResult CheckSingleRule(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as LeakyBucketRule;
            var amount      = 1;

            #region local attribute

            if (rateLimitAttrData != null && rateLimitAttrData.LeakyBucketLimitAttribute != null)
            {
                currentRule.Capacity = rateLimitAttrData.LeakyBucketLimitAttribute.Capacity;
                currentRule.OutflowQuantityPerUnit  = rateLimitAttrData.LeakyBucketLimitAttribute.OutflowQuantityPerUnit;
                currentRule.OutflowUnit             = CommonUtils.Parse(rateLimitAttrData.LeakyBucketLimitAttribute.Period);
                currentRule.RateLimitExceptionThrow = rateLimitAttrData.LeakyBucketLimitAttribute.RateLimitExceptionThrow;
            }

            #endregion local attribute

            var result = InnerCheckSingleRule(target, amount, currentRule);
            return(new RuleCheckResult()
            {
                IsLimit = result.Item1,
                Target = target,
                Count = result.Item2,
                Rule = rule,
                Wait = result.Item3,
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }
        /// <summary>
        /// check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <param name="rateLimitAttrData"></param>
        /// <returns></returns>
        protected override RuleCheckResult CheckSingleRule(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as TokenBucketRule;
            var amount      = 1;

            #region check controller of method mark TokenbucketAttribute is priority compare with global service.AddRamitLimit

            if (rateLimitAttrData != null && rateLimitAttrData.TokenBucketLimitAttribute != null)
            {
                currentRule.Capacity = rateLimitAttrData.TokenBucketLimitAttribute.Capacity;
                currentRule.InflowQuantityPerUnit   = rateLimitAttrData.TokenBucketLimitAttribute.InflowQuantityPerUnit;
                currentRule.InflowUnit              = CommonUtils.Parse(rateLimitAttrData.TokenBucketLimitAttribute.Period);
                currentRule.RateLimitExceptionThrow = rateLimitAttrData.TokenBucketLimitAttribute.RateLimitExceptionThrow;
            }

            #endregion check controller of method mark TokenbucketAttribute is priority compare with global service.AddRamitLimit

            var result = InnerCheckSingleRule(target, amount, currentRule);
            return(new RuleCheckResult()
            {
                IsLimit = result.Item1,
                Target = target,
                Count = result.Item2,
                Rule = rule,
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override async Task <RuleCheckResult> CheckSingleRuleAsync(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as SlidingWindowRule;
            var amount      = 1;

            #region local attribute

            if (rateLimitAttrData != null && rateLimitAttrData.SlidingWindowLimitAttribute != null)
            {
                currentRule.LimitNumber  = rateLimitAttrData.SlidingWindowLimitAttribute.LimitNumber;
                currentRule.StatWindow   = CommonUtils.Parse(rateLimitAttrData.SlidingWindowLimitAttribute.StatWindowPeriod);
                currentRule.StatPeriod   = CommonUtils.Parse(rateLimitAttrData.SlidingWindowLimitAttribute.StatSmallPeriod);
                currentRule.PeriodNumber = (int)(currentRule.StatWindow.TotalMilliseconds / currentRule.StatPeriod.TotalMilliseconds);
            }

            #endregion local attribute

            var currentTime = await _timeProvider.GetCurrentUtcMillisecondsAsync();

            var  startTime          = AlgorithmStartTime.ToSpecifiedTypeTime(currentTime, currentRule.StatWindow, currentRule.StartTimeType);
            long expireMilliseconds = ((long)currentRule.StatWindow.TotalMilliseconds) * 2;
            long periodMilliseconds = (long)currentRule.StatPeriod.TotalMilliseconds;

            var ret = (long[]) await EvaluateScriptAsync(_slidingWindowIncrementLuaScript,
                                                         new RedisKey[] { target },
                                                         new RedisValue[] { amount, expireMilliseconds, periodMilliseconds, currentRule.PeriodNumber, currentTime, startTime, currentRule.LimitNumber, currentRule.LockSeconds });

            return(new RuleCheckResult()
            {
                IsLimit = ret[0] == 0 ? false : true,
                Target = target,
                Count = ret[1],
                Rule = rule,
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }
        /// <summary>
        /// check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override RuleCheckResult CheckSingleRule(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as FixedWindowRule;
            var amount      = 1;

            #region local attribute

            if (rateLimitAttrData != null && rateLimitAttrData.FixedWindowLimitAttribute != null)
            {
                currentRule.LimitNumber             = rateLimitAttrData.FixedWindowLimitAttribute.LimitNumber;
                currentRule.StatWindow              = CommonUtils.Parse(rateLimitAttrData.FixedWindowLimitAttribute.Period);
                currentRule.RateLimitExceptionThrow = rateLimitAttrData.FixedWindowLimitAttribute.RateLimitExceptionThrow;
            }

            #endregion local attribute

            var result = InnerCheckSingleRule(target, amount, currentRule);
            return(new RuleCheckResult()
            {
                IsLimit = result.Item1,
                Target = target,
                Count = result.Item2,
                Rule = rule,
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }
        /// <summary>
        /// async check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        protected override async Task <RuleCheckResult> CheckSingleRuleAsync(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as LeakyBucketRule;
            var amount      = 1;

            #region local attribute

            if (rateLimitAttrData != null && rateLimitAttrData.LeakyBucketLimitAttribute != null)
            {
                currentRule.Capacity = rateLimitAttrData.LeakyBucketLimitAttribute.Capacity;
                currentRule.OutflowQuantityPerUnit  = rateLimitAttrData.LeakyBucketLimitAttribute.OutflowQuantityPerUnit;
                currentRule.OutflowUnit             = CommonUtils.Parse(rateLimitAttrData.LeakyBucketLimitAttribute.Period);
                currentRule.RateLimitExceptionThrow = rateLimitAttrData.LeakyBucketLimitAttribute.RateLimitExceptionThrow;
            }

            #endregion local attribute

            // can not call redis TIME command in script
            var outflowUnit = currentRule.OutflowUnit.TotalMilliseconds;
            var currentTime = await _timeProvider.GetCurrentUtcMillisecondsAsync();

            var startTime = AlgorithmStartTime.ToSpecifiedTypeTime(currentTime, TimeSpan.FromMilliseconds(outflowUnit), currentRule.StartTimeType);

            var ret = (long[]) await EvaluateScriptAsync(_leakyBucketIncrementLuaScript, new RedisKey[] { target },
                                                         new RedisValue[] { amount, currentRule.Capacity, outflowUnit, currentRule.OutflowQuantityPerUnit, currentTime, startTime, currentRule.LockSeconds });

            return(new RuleCheckResult()
            {
                IsLimit = ret[0] == 0 ? false : true,
                Target = target,
                Count = ret[1],
                Rule = rule,
                Wait = ret[2],
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }
        /// <summary>
        /// async check single rule for target
        /// </summary>
        /// <param name="target"></param>
        /// <param name="rule"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        protected override async Task <RuleCheckResult> CheckSingleRuleAsync(string target, RateLimitRule rule, RateLimitTypeAttributeJson rateLimitAttrData = null)
        {
            var currentRule = rule as TokenBucketRule;
            var amount      = 1;

            //check controller of method mark TokenbucketAttribute is priority compare with global service.AddRamitLimit
            if (rateLimitAttrData != null && rateLimitAttrData.TokenBucketLimitAttribute != null)
            {
                currentRule.Capacity = rateLimitAttrData.TokenBucketLimitAttribute.Capacity;
                currentRule.InflowQuantityPerUnit   = rateLimitAttrData.TokenBucketLimitAttribute.InflowQuantityPerUnit;
                currentRule.InflowUnit              = CommonUtils.Parse(rateLimitAttrData.TokenBucketLimitAttribute.Period);
                currentRule.RateLimitExceptionThrow = rateLimitAttrData.TokenBucketLimitAttribute.RateLimitExceptionThrow;
            }
            var inflowUnit  = currentRule.InflowUnit.TotalMilliseconds;
            var currentTime = await _timeProvider.GetCurrentUtcMillisecondsAsync();

            var startTime = AlgorithmStartTime.ToSpecifiedTypeTime(currentTime, TimeSpan.FromMilliseconds(inflowUnit), currentRule.StartTimeType);

            var ret = (long[]) await EvaluateScriptAsync(_tokenBucketDecrementLuaScript, new RedisKey[] { target },
                                                         new RedisValue[] { amount, currentRule.Capacity, inflowUnit, currentRule.InflowQuantityPerUnit, currentTime, startTime, currentRule.LockSeconds });

            var result = new Tuple <bool, long>(ret[0] == 0 ? false : true, ret[1]);

            return(new RuleCheckResult()
            {
                IsLimit = result.Item1,
                Target = target,
                Count = result.Item2,
                Rule = rule,
                RateLimitExceptionThrow = currentRule.RateLimitExceptionThrow
            });
        }