BlossomiShymae / RiotBlossom

An asynchronous, extensible, and magical Riot Games API wrapper library for C#. ☆*:.。.o(≧▽≦)o.。.:*☆
https://blossomishymae.github.io/RiotBlossom/
MIT License
13 stars 2 forks source link

Request limit #42

Open Alcamoru opened 1 year ago

Alcamoru commented 1 year ago

Hey, I'm new to C# and to coding so be kind if my question is not pertinent. I know that Riot Games request limit is 20 requests per second. I'm getting sometimes a "TooManyRequestsException, and my program is only getting matchlist (very small program). I'm having this issue while using the ListIdsByPuuidAsync while working with League of Legends API. Capture d'écran 2023-07-29 222717 Capture d'écran 2023-07-29 222751 I think that the issue is caused by the Count parameter because when there are only 5 or 10 matches to retrieve, there is no problem, but when I ask up to 100 matches, the issue happens I don't have yet the C# skills to see the source code on my own deeply so idk but this issue don't happen with other Api's packages (like in Python), so I just wanted to know if it's just a normal behavior, and the Riot request limit is normal. Thanks a lot for your great work 🙌👍

BlossomiShymae commented 1 year ago

Hiya! 💜

Thanks for submitting an issue about this. It's okie dokie if you're new to C#, we're always learning new things along the way!

Riot API rate limits are dynamically set based on your API key, which the library attempts to account for. There are other dynamic limits besides the 20 requests per second. TooManyRequestsException means an actual 429 response code happened, and that isn't good. I was able to reproduce with minimal configuration so it must be something to do with the spread rate limiter. x.x

You can do this for the configuration as a workaround for now (let me know if it works for you):

string key = Environment.GetEnvironmentVariable("RIOT_API_KEY")
    ?? throw new InvalidOperationException("RIOT_API_KEY must be set!");
var client = RiotBlossomCore.CreateClientBuilder()
    .AddRiotApiKey(key)
    .AddRiotMiddlewareStack(b =>
    {
        b.AddInMemoryCache(new("rb-riot-cache"));
        b.AddAlgorithmicLimiter(new(new() 
        {
          CanThrowOnLimit = false,
          ShaperType = LimiterShaper.Burst
        }));
        b.AddRetryer(new());
        return b;
    })
    .AddDataMiddlewareStack(b =>
    {
        b.AddInMemoryCache(new("rb-data-cache"));
        b.AddRetryer(new());
        return b;
    })
    .Build();

Do note that this will automatically await the full retry period when a rate limit is exhausted. If this isn't what you want, you can manually handle the WarningLimiterException yourself by setting CanThrowOnLimit to true. The exception should contain the estimated retry duration as a TimeSpan :3

Alcamoru commented 1 year ago

Thanks so much ! It worked perfectly for me !🤩