Skip to content

Commit

Permalink
Make RateLimitPartition.Factory public (#71145)
Browse files Browse the repository at this point in the history
* Make RateLimitPartition.Factory public

* Fix tests

* Fix comment
  • Loading branch information
wtgodbe authored Jun 22, 2022
1 parent 78a2627 commit 9bb393c
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public partial struct RateLimitPartition<TKey>
private int _dummyPrimitive;
public RateLimitPartition(TKey partitionKey, System.Func<TKey, System.Threading.RateLimiting.RateLimiter> factory) { throw null; }
public readonly TKey PartitionKey { get { throw null; } }
public readonly Func<TKey, RateLimiter> Factory { get { throw null; } }
}
public abstract partial class ReplenishingRateLimiter : System.Threading.RateLimiting.RateLimiter
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public RateLimitPartition(TKey partitionKey, Func<TKey, RateLimiter> factory)
/// </summary>
public TKey PartitionKey { get; }

internal readonly Func<TKey, RateLimiter> Factory;
/// <summary>
/// The function called when a rate limiter for the given partitionKey is needed.
/// </summary>
public Func<TKey, RateLimiter> Factory { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ public void Create_Concurrency()
var options = new ConcurrencyLimiterOptions(10, QueueProcessingOrder.OldestFirst, 10);
var partition = RateLimitPartition.CreateConcurrencyLimiter(1, key => options);

var factoryProperty = typeof(RateLimitPartition<int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!;
var factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition);
var limiter = factory(1);
var limiter = partition.Factory(1);
var concurrencyLimiter = Assert.IsType<ConcurrencyLimiter>(limiter);
Assert.Equal(options.PermitLimit, concurrencyLimiter.GetAvailablePermits());
}
Expand All @@ -27,9 +25,7 @@ public void Create_TokenBucket()
var options = new TokenBucketRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 10, TimeSpan.FromMinutes(1), 1, true);
var partition = RateLimitPartition.CreateTokenBucketLimiter(1, key => options);

var factoryProperty = typeof(RateLimitPartition<int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!;
var factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition);
var limiter = factory(1);
var limiter = partition.Factory(1);
var tokenBucketLimiter = Assert.IsType<TokenBucketRateLimiter>(limiter);
Assert.Equal(options.TokenLimit, tokenBucketLimiter.GetAvailablePermits());
Assert.Equal(options.ReplenishmentPeriod, tokenBucketLimiter.ReplenishmentPeriod);
Expand All @@ -41,9 +37,7 @@ public async Task Create_NoLimiter()
{
var partition = RateLimitPartition.CreateNoLimiter(1);

var factoryProperty = typeof(RateLimitPartition<int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!;
var factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition);
var limiter = factory(1);
var limiter = partition.Factory(1);

// How do we test an internal implementation of a limiter that doesn't limit? Just try some stuff that normal limiters would probably block on and see if it works.
var available = limiter.GetAvailablePermits();
Expand All @@ -67,15 +61,12 @@ public void Create_AnyLimiter()
{
var partition = RateLimitPartition.Create(1, key => new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 10)));

var factoryProperty = typeof(RateLimitPartition<int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!;
var factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition);
var limiter = factory(1);
var limiter = partition.Factory(1);
var concurrencyLimiter = Assert.IsType<ConcurrencyLimiter>(limiter);
Assert.Equal(1, concurrencyLimiter.GetAvailablePermits());

var partition2 = RateLimitPartition.Create(1, key => new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions(1, QueueProcessingOrder.NewestFirst, 10, TimeSpan.FromMilliseconds(100), 1, autoReplenishment: false)));
factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition2);
limiter = factory(1);
limiter = partition2.Factory(1);
var tokenBucketLimiter = Assert.IsType<TokenBucketRateLimiter>(limiter);
Assert.Equal(1, tokenBucketLimiter.GetAvailablePermits());
}
Expand All @@ -86,9 +77,7 @@ public void Create_FixedWindow()
var options = new FixedWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 10, TimeSpan.FromMinutes(1), true);
var partition = RateLimitPartition.CreateFixedWindowLimiter(1, key => options);

var factoryProperty = typeof(RateLimitPartition<int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!;
var factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition);
var limiter = factory(1);
var limiter = partition.Factory(1);
var fixedWindowLimiter = Assert.IsType<FixedWindowRateLimiter>(limiter);
Assert.Equal(options.PermitLimit, fixedWindowLimiter.GetAvailablePermits());
Assert.Equal(options.Window, fixedWindowLimiter.ReplenishmentPeriod);
Expand All @@ -101,9 +90,7 @@ public void Create_SlidingWindow()
var options = new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 10, TimeSpan.FromSeconds(33), 3, true);
var partition = RateLimitPartition.CreateSlidingWindowLimiter(1, key => options);

var factoryProperty = typeof(RateLimitPartition<int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!;
var factory = (Func<int, RateLimiter>)factoryProperty.GetValue(partition);
var limiter = factory(1);
var limiter = partition.Factory(1);
var slidingWindowLimiter = Assert.IsType<SlidingWindowRateLimiter>(limiter);
Assert.Equal(options.PermitLimit, slidingWindowLimiter.GetAvailablePermits());
Assert.Equal(TimeSpan.FromSeconds(11), slidingWindowLimiter.ReplenishmentPeriod);
Expand Down

0 comments on commit 9bb393c

Please sign in to comment.