-
Notifications
You must be signed in to change notification settings - Fork 286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle a rate-limited API #93
Comments
What kind of example did you have in mind here? The way rate limiting is handled will necessarily vary depending on which API you are communicating with. For example, GitHub always replies with a So a hypothetical request to some GitHub API might go like this:
Or were you thinking of patterns people can use to make sure they don't go over their rate limit (e.g. the Leaky Bucket algorithm)? |
@konstin you suggested this one initially. Any thoughts? |
The correct solution would be a crate that is hooked into hyper and/or rewquest. This crate would delay all requests until you're allowed to requests again while logging to the user. Unfortunately, no stable crate for that currently exists. There a two custom solutions: Github's api is friendly enough telling you the number of remaining requests, so you'd just check that header and sleep if the number gets to low. As most apis aren't that helpfull though, the best solution is essentially trial and error, which I've quickly sketched out below. Consider the code as pseudocode, it's only meant to explain the control flow. fn rate_limit_agnostic_request(url: Url) -> Result<String, Box<Error>> {
loop {
let mut reponse = reqwest::get(&url)?;
if reponse.status().is_success() {
let mut string = String::new();
reponse.read_to_string(&mut string)?;
return Ok(string);
} else if reponse.status() == TooManyRequests {
info!("Rate limit hit, sleeping for 5 seconds");
sleep(Seconds::new(5)); // TODO: Find the right functions for that
} else { // Some other error
return Err(from::From("Some other error"));
}
}
} |
Side note: I wouldn't label this easy. Doing this right is surprisingly difficult, esp. when it comes to parallelism. This is made even more difficult by the fact that many services do not even adhere the http standard, which is to return a 429 and a |
So fun fact, I was actually working on solving this problem myself and found the I think it'd be good to have two different rate-limiting examples: one that takes the proactive approach (rate limiting on the client side, only submitting requests at a certain rate) and one that takes the reactive approach (creating a handler that will retry rate-limited requests). They both have different use cases; code that sends requests based upon events would prefer a reactive method, whereas code that sends batches of requests would prefer a proactive method (potentially paired with a reactive method). It might make sense to add ways of handling the reactive method to reqwest (for all of the sorts of non-standard variations listed), although I think that there should be some examples for the |
Hi @clarcharr, Thanks for looking into this! We would certainly love to have both types of rate limiting examples as long as these are relatively bytesized (the draw fractal seams to be near our pain threshold). Originally we have hoped to present some trivial example without additional crates. At the moment the cookbook tries to follow crates covered by Libz Blitz initiative. These crates are guaranteed to be of (or soon reach) high quality which is crucial for learning/reference resource such as cookbook. So I would be hesitant to add another relatively new crate just yet. But feel free to submit |
I can progress this if no one is currently working on it. And handle to specific cases.
|
I'd suggest implementing just one version with a comment that you can do all the other ways easily by adapting that code. |
In that case Another question is about how this will be tested, since httpbin.org doesn't have a way to test this, and the other ones require an user account (not an issue during the implementation, but). |
Personally I would go with github api. It's rate limited (the limit is much stricter if unauthorized) |
At this moment we are looking for volunteer to finish up the PR by @jbolila |
Hitting a rate limit may either return an error for the request or return a JSON body that is different from the usual. Let's show how to deal with one or both of these cases.
The text was updated successfully, but these errors were encountered: