/// <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)); }
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)); }
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)); }
public ApiResultImpl(T result, long limit, long remain, DateTime reset) { RateLimit = new RateLimitDescription(limit, remain, reset); Result = result; }
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); }
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); }