C
C#2y 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
Doombox2y 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
Accord2y ago
✅ This post has been marked as answered!
Want results from more Discord servers?
Add your server
More Posts
Abstract List of KeyValuePairs```cs public abstract List<KeyValuePair<string, int>> inventory;``` It says I can't do this with a fMAUI navigation to new page with injected viewModelIf you think this belong more into #mobile channel I can move, but I think some of you who are morecatching an exception in an async Task [Answered]I can't seem to catch an exception that is thrown in an async Task, I put try/catch within the asyncpass data onclick from one page to another page in asp nethi all, im trying to redirect a page from **Main Page** to **Sub Page** when i click an item on **MASP NET Core default DI-Container, how pass in constructor not-registered parameter? [Answered]I want to create a Model class using a DI container, services registered in the container are passedShould I return the whole created object in POST or just return the id of that object ?When I creating a post method I find myself repeat what I did in GetById Should I just return the Iasp net cshtml javascript filehi all, i have an asp net project (SimpleApp) and in a cshtml file of my **SimpleApp ** project i trChange Visual Studio suggetions with custom analysersHiya.. ohh discords new "forum" channels are super useful for this huh?. anyway. So I managed to impProgram won’t run with just .net runtime [Answered]So my program that I published and is targeting .net 6 won’t run when the pc has just .net 6 runtimeNullReferenceException Object reference not set to an instance of an object```cs List<Effects> effectsList = activePlayerEffects[targetPlayer] ?? new List<Effects>(); ``` some