public void Create_SlidingWindow() { var options = new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 10, TimeSpan.FromSeconds(33), 3, true); var partition = RateLimitPartition.GetSlidingWindowLimiter(1, key => options); var limiter = partition.Factory(1); var slidingWindowLimiter = Assert.IsType <SlidingWindowRateLimiter>(limiter); Assert.Equal(options.PermitLimit, slidingWindowLimiter.GetAvailablePermits()); Assert.Equal(TimeSpan.FromSeconds(11), slidingWindowLimiter.ReplenishmentPeriod); Assert.False(slidingWindowLimiter.IsAutoReplenishing); }
/// <summary> /// Defines a partition with a <see cref="SlidingWindowRateLimiter"/> with the given <see cref="SlidingWindowRateLimiterOptions"/>. /// </summary> /// <remarks> /// Set <see cref="SlidingWindowRateLimiterOptions.AutoReplenishment"/> to <see langword="false"/> to save an allocation. This method will create a new options type and set <see cref="SlidingWindowRateLimiterOptions.AutoReplenishment"/> to <see langword="false"/> otherwise. /// </remarks> /// <typeparam name="TKey">The type to distinguish partitions with.</typeparam> /// <param name="partitionKey">The specific key for this partition.</param> /// <param name="factory">The function called when a rate limiter for the given <paramref name="partitionKey"/> is needed. This can return the same instance of <see cref="SlidingWindowRateLimiterOptions"/> across different calls.</param> /// <returns></returns> public static RateLimitPartition <TKey> GetSlidingWindowLimiter <TKey>( TKey partitionKey, Func <TKey, SlidingWindowRateLimiterOptions> factory) { return(Get(partitionKey, key => { SlidingWindowRateLimiterOptions options = factory(key); // We don't want individual SlidingWindowRateLimiters to have timers. We will instead have our own internal Timer handling all of them if (options.AutoReplenishment is true) { options = new SlidingWindowRateLimiterOptions(options.PermitLimit, options.QueueProcessingOrder, options.QueueLimit, options.Window, options.SegmentsPerWindow, autoReplenishment: false); } return new SlidingWindowRateLimiter(options); })); }
/// <summary> /// Adds a new <see cref="SlidingWindowRateLimiter"/> with the given <see cref="SlidingWindowRateLimiterOptions"/> to the <see cref="RateLimiterOptions"/>. /// </summary> /// <param name="options">The <see cref="RateLimiterOptions"/> to add a limiter to.</param> /// <param name="policyName">The name that will be associated with the limiter.</param> /// <param name="configureOptions">A callback to configure the <see cref="SlidingWindowRateLimiterOptions"/> to be used for the limiter.</param> /// <returns>This <see cref="RateLimiterOptions"/>.</returns> public static RateLimiterOptions AddSlidingWindowLimiter(this RateLimiterOptions options, string policyName, Action <SlidingWindowRateLimiterOptions> configureOptions) { ArgumentNullException.ThrowIfNull(configureOptions); var key = new PolicyNameKey() { PolicyName = policyName }; var slidingWindowRateLimiterOptions = new SlidingWindowRateLimiterOptions(); configureOptions.Invoke(slidingWindowRateLimiterOptions); // Saves an allocation in GetSlidingWindowLimiter, which would have created a new set of options if this was true. slidingWindowRateLimiterOptions.AutoReplenishment = false; return(options.AddPolicy(policyName, context => { return RateLimitPartition.GetSlidingWindowLimiter(key, _ => slidingWindowRateLimiterOptions); })); }
public void Create_SlidingWindow() { var options = new SlidingWindowRateLimiterOptions { PermitLimit = 1, QueueProcessingOrder = QueueProcessingOrder.OldestFirst, QueueLimit = 10, Window = TimeSpan.FromSeconds(33), SegmentsPerWindow = 3, AutoReplenishment = true }; var partition = RateLimitPartition.GetSlidingWindowLimiter(1, key => options); var limiter = partition.Factory(1); var slidingWindowLimiter = Assert.IsType <SlidingWindowRateLimiter>(limiter); Assert.Equal(options.PermitLimit, slidingWindowLimiter.GetStatistics().CurrentAvailablePermits); Assert.Equal(TimeSpan.FromSeconds(11), slidingWindowLimiter.ReplenishmentPeriod); Assert.False(slidingWindowLimiter.IsAutoReplenishing); }