public Task <ThrottleCounter> IncrementAsync(string key, ThrottleRequirement requirement, long incrementValue = 1, bool reachLimitAtMax = false)
        {
            bool limitReached          = false;
            ThrottleCounterEntry entry = _cache.Get <ThrottleCounterEntry>(key);

            if (entry == null)
            {
                entry = new ThrottleCounterEntry
                {
                    Reset = _clock.UtcNow.Add(requirement.RenewalPeriod),
                    Value = incrementValue
                };
            }
            else
            {
                var value = entry.Value + incrementValue;
                if (value > requirement.MaxValue || (reachLimitAtMax && value == requirement.MaxValue))
                {
                    limitReached = true;
                }

                entry.Value = value;

                if (requirement.Sliding)
                {
                    entry.Reset = _clock.UtcNow.Add(requirement.RenewalPeriod);
                }
            }

            _cache.Set(key, entry, entry.Reset);

            var counter = new ThrottleCounter(entry.Reset, entry.Value, limitReached);

            return(Task.FromResult(counter));
        }
        public override void AddRateLimitHeaders(ThrottleCounter counter, ThrottleContext throttleContext, IPSessionRateLimitRequirement requirement)
        {
            if (counter == null)
            {
                throw new ArgumentNullException(nameof(counter));
            }

            if (throttleContext == null)
            {
                throw new ArgumentNullException(nameof(throttleContext));
            }

            if (requirement == null)
            {
                throw new ArgumentNullException(nameof(requirement));
            }

            throttleContext.ResponseHeaders["X-RateLimit-IPLimit"]     = requirement.MaxValue.ToString();
            throttleContext.ResponseHeaders["X-RateLimit-IPRemaining"] = counter.Remaining(requirement).ToString();
        }
        public Task <ThrottleCounter> GetAsync(string key, ThrottleRequirement requirement)
        {
            ThrottleCounter      counter;
            ThrottleCounterEntry item = _cache.Get <ThrottleCounterEntry>(key);

            if (item == null)
            {
                counter = new ThrottleCounter(_clock.UtcNow.Add(requirement.RenewalPeriod));
            }
            else
            {
                bool limitReached = false;
                if (item.Value >= requirement.MaxValue)
                {
                    limitReached = true;
                }

                counter = new ThrottleCounter(item.Reset, item.Value, limitReached);
            }

            return(Task.FromResult(counter));
        }
 public abstract void AddRateLimitHeaders(ThrottleCounter counter, ThrottleContext throttleContext, TRequirement requirement);