C
C#3y ago
Doombox

Using multiple RateLimiters correctly. [Answered]

I'm wrapping an API which requires no more than 4 requests per second and 200 per hour, I've got a setup like this
_hourlyRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
200, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromHours(1)));
_secondRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
4, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromSeconds(1)));
// ...
public async Task Test(int testNumber)
{
var hourly = _hourlyRateLimiter.WaitAsync();
var second = _secondRateLimiter.WaitAsync();
await ValueTaskExtensions.WhenAll(hourly, second);
Console.WriteLine(testNumber);
}
_hourlyRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
200, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromHours(1)));
_secondRateLimiter = new FixedWindowRateLimiter(new FixedWindowRateLimiterOptions(
4, QueueProcessingOrder.OldestFirst, 1, TimeSpan.FromSeconds(1)));
// ...
public async Task Test(int testNumber)
{
var hourly = _hourlyRateLimiter.WaitAsync();
var second = _secondRateLimiter.WaitAsync();
await ValueTaskExtensions.WhenAll(hourly, second);
Console.WriteLine(testNumber);
}
this works well if you await each call of Test, however if you try something like this...
var tasks = new List<Task>();
for (var i = 0; i < 250; i++)
tasks.Add(Test(i));
await Task.WhenAll(tasks);
var tasks = new List<Task>();
for (var i = 0; i < 250; i++)
tasks.Add(Test(i));
await Task.WhenAll(tasks);
the rate limiter seems to break, have I written this poorly or is this just an issue with concurrency in the library?
2 Replies
Doombox
DoomboxOP3y ago
and by break I mean it literally spits out the entire 250 tasks instantly oh, except the 5th one, which seems to be spit out one second after thonk I'm an idiot, never mind, you would have to set the queueLimit to a large enough number to handle all those tasks being queued at once, the WaitAsync call returns a lease that tells you if it was successful or not, though it does still seem to let 5 items through despite the limit being 4 per second, not quite sure how it manages that but there we go
Accord
Accord3y ago
✅ This post has been marked as answered!
Want results from more Discord servers?
Add your server