/// <summary> /// Gets a <see cref="RequestCounter"/> that counted the current request according the specified rule. /// </summary> /// <param name="request">The client request object.</param> /// <param name="rule">The throttle rule.</param> /// <returns>The corresponding counter for the request.</returns> public RequestCounter ProcessRequest(ClientRequest request, ThrottleRule rule) { if (rule.PeriodTimespan == null) { throw new InvalidOperationException("Throttle period time span is not set!"); } var key = GetStorageKey(request, rule); var counter = _counterStore.GetOrCreate( key, () => new RequestCounter { Timestamp = DateTime.UtcNow, TotalRequests = 0 }, rule.PeriodTimespan.Value); counter.Increment(); // Checks limit and enters cool down period by prolonging the counter expiration. if (counter.TotalRequests > rule.Limit && !counter.LimitExceeded) { counter.LimitExceeded = true; if (rule.CooldownTimespan.HasValue && DateTime.UtcNow + rule.CooldownTimespan.Value > counter.Timestamp + rule.PeriodTimespan.Value) { _counterStore.Set(key, counter, rule.CooldownTimespan.Value); } } return(counter); }
private string GetStorageKey(ClientRequest request, ThrottleRule rule) { return($"{Options.ThrottleName}_{request.ClientId}_{rule.Id}".Sha1()); }