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 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 long Remaining(ThrottleRequirement requirement)
 {
     return(Value > requirement.MaxValue ? 0 : requirement.MaxValue - Value);
 }