예제 #1
0
 /// <summary>
 /// Create IApiResult object with specified RateLimitDescription.
 /// </summary>
 /// <typeparam name="T">type of result</typeparam>
 /// <param name="item">result item</param>
 /// <param name="description">rate limit description</param>
 /// <returns></returns>
 public static IApiResult <T> Create <T>([NotNull] T item, RateLimitDescription description)
 {
     if (item == null)
     {
         throw new ArgumentNullException(nameof(item));
     }
     return(new ApiResultImpl <T>(item, description.Limit, description.Remain, description.Reset));
 }
예제 #2
0
        protected override long CalculateIntervalTicks(TimeSpan remain, RateLimitDescription rld)
        {
            int count;

            lock (_targetLists)
            {
                count = _targetLists.Count;
            }
            if (count == 0)
            {
                // list receiver is empty -> re-evaluate 5 seconds later.
                return(TimeSpan.FromSeconds(5).Ticks);
            }
            // based on rate-limit description
            var rldintv = (long)(remain.Ticks / (rld.Remain * ApiConsumptionLimitRatio));
            // based on list count
            var lcintv = TimeSpan.FromSeconds(BaseAccessIntervalSec).Ticks / count;

            // choose larger interval
            return(Math.Max(rldintv, lcintv));
        }
예제 #3
0
        protected virtual long CalculateIntervalTicks(TimeSpan remain, RateLimitDescription rld)
        {
            if (_lastRateLimitDescription != null)
            {
                // estimate api consumption
                var delta = _lastRateLimitDescription.Value.Remain - rld.Remain;
                if (delta > 0)
                {
                    // sliding average
                    _averageApiConsumption = _averageApiConsumption * 0.3 + delta * 0.7;
                }
            }
            else
            {
                _averageApiConsumption = rld.Limit - rld.Remain;
            }
            _lastRateLimitDescription = rld;
            var inferCallableCount = rld.Remain * ApiConsumptionLimitRatio / _averageApiConsumption;
            var tick      = (long)(remain.Ticks / inferCallableCount);
            var resetTick = (rld.Reset - DateTime.Now).Ticks;

            // if calculated wait tick is after the reset tick, we should use reset tick.
            return(Math.Min(tick, resetTick));
        }
예제 #4
0
 public ApiResultImpl(T result, long limit, long remain, DateTime reset)
 {
     RateLimit = new RateLimitDescription(limit, remain, reset);
     Result    = result;
 }
예제 #5
0
 protected virtual long CalculateIntervalTicks(TimeSpan remain, RateLimitDescription rld)
 {
     if (_lastRateLimitDescription != null)
     {
         // estimate api consumption
         var delta = _lastRateLimitDescription.Value.Remain - rld.Remain;
         if (delta > 0)
         {
             // sliding average
             _averageApiConsumption = _averageApiConsumption * 0.3 + delta * 0.7;
         }
     }
     else
     {
         _averageApiConsumption = rld.Limit - rld.Remain;
     }
     _lastRateLimitDescription = rld;
     var inferCallableCount = rld.Remain * ApiConsumptionLimitRatio / _averageApiConsumption;
     var tick = (long)(remain.Ticks / inferCallableCount);
     var resetTick = (rld.Reset - DateTime.Now).Ticks;
     // if calculated wait tick is after the reset tick, we should use reset tick.
     return Math.Min(tick, resetTick);
 }
예제 #6
0
 protected override long CalculateIntervalTicks(TimeSpan remain, RateLimitDescription rld)
 {
     int count;
     lock (_targetLists)
     {
         count = _targetLists.Count;
     }
     if (count == 0)
     {
         // list receiver is empty -> re-evaluate 5 seconds later.
         return TimeSpan.FromSeconds(5).Ticks;
     }
     // based on rate-limit description
     var rldintv = (long)(remain.Ticks / (rld.Remain * ApiConsumptionLimitRatio));
     // based on list count
     var lcintv = TimeSpan.FromSeconds(BaseAccessIntervalSec).Ticks / count;
     // choose larger interval
     return Math.Max(rldintv, lcintv);
 }