Esempio n. 1
0
        /// <summary>
        /// <para>
        /// The returned <code>RateLimiter</code> is intended for cases where the resource that actually
        /// fulfills the requests (e.g., a remote server) needs "warmup" time, rather than
        /// being immediately accessed at the stable (maximum) rate.
        /// </para>
        /// <para>
        /// The returned <code>RateLimiter</code> starts in a "cold" state (i.e. the warmup period
        /// will follow), and if it is left unused for long enough, it will return to that state.
        /// </para>
        /// </summary>
        /// <param name="permitsPerSecond">The rate of the returned <code>RateLimiter</code>, measured in how many permits become available per second</param>
        /// <param name="warmupPeriod">The duration of the period where the <code>RateLimiter</code> ramps up its rate, before reaching its stable (maximum) rate</param>
        /// <param name="unit">The time unit of the warmupPeriod argument</param>
        /// <param name="coldFactor"></param>
        public static RateLimiter Create(double permitsPerSecond, long warmupPeriod, TimeUnit unit = TimeUnit.Seconds, double coldFactor = 3.0)
        {
            if (warmupPeriod < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(warmupPeriod), "WarmupPeriod must not be negative");
            }

            return(Create(SleepingStopwatch.CreateFromSystemTimer(), permitsPerSecond, warmupPeriod, unit, coldFactor));
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a <code>RateLimiter</code> with the specified stable throughput, given as "permits per second"
        /// </summary>
        /// <remarks>
        /// Creates a <code>RateLimiter</code> with the specified stable throughput, given as
        /// "permits per second" (commonly referred to as QPS, queries per second).
        ///
        /// The returned <code>RateLimiter</code> ensures that on average no more than <code>permitsPerSecond</code>
        /// are issued during any given second, with sustained requests
        /// being smoothly spread over each second. When the incoming request rate exceeds
        /// <code>permitsPerSecond</code> the rate limiter will release one permit every
        /// <code>(1.0 / permitsPerSecond)</code> seconds. When the rate limiter is unused,
        /// bursts of up to <code>permitsPerSecond</code> permits will be allowed, with subsequent
        /// requests being smoothly limited at the stable rate of <code>permitsPerSecond</code>.
        /// </remarks>
        /// <param name="permitsPerSecond">
        /// The rate of the returned <code>RateLimiter</code>, measured in how many permits become available per second
        /// </param>
        public static RateLimiter Create(double permitsPerSecond)
        {
            /*  The default RateLimiter configuration can save the unused permits of up to one second.
             *  This is to avoid unnecessary stalls in situations like this: A RateLimiter of 1qps,
             *  and 4 threads, all calling acquire() at these moments:
             *
             *  T0 at 0 seconds
             *  T1 at 1.05 seconds
             *  T2 at 2 seconds
             *  T3 at 3 seconds
             *
             *  Due to the slight delay of T1, T2 would have to sleep till 2.05 seconds,
             *  and T3 would also have to sleep till 3.05 seconds. */

            return(Create(SleepingStopwatch.CreateFromSystemTimer(), permitsPerSecond));
        }