/// <summary> /// advance calculates and returns an updated state for lim resulting from the passage of time. /// lim is not changed. /// advance requires that lim.mu is held. /// </summary> /// <param name="now">The now.</param> private (DateTimeOffset newNow, DateTimeOffset newLast, double newTokens) Advance(DateTimeOffset now) { lock (_sync) { var last = _last; if (now < last) { last = now; } // Avoid making delta overflow below when last is very old. var maxElapsed = _limit.DurationFromTokens(_burst - _tokens); var elapsed = now - last; if (elapsed > maxElapsed) { elapsed = maxElapsed; } // Calculate the new number of tokens, due to time that passed. var delta = _limit.TokensFromDuration(elapsed); var tokens = _tokens + delta; if (tokens > _burst) { tokens = _burst; } return(now, last, tokens); } }
public void TokensFromDuration(double perSecond, double durationSeconds, double tokens) { // arrange var limit = new Limit(perSecond); // act var tokensFromDuration = limit.TokensFromDuration(TimeSpan.FromSeconds(durationSeconds)); // assert tokensFromDuration.ShouldBe(tokens); }