-
So, as far as I know there is not a build-in way in the library to handle 429 responses (too many requests) coming from a graph call when throttling kicks in. I also feel like the current Library Api makes it really hard to handle retries in a generic way. I can't create a generic function that takes a IntoResponse<T, Clinet> as it does not implement clone (to send, parse the error, and then send again after a delay) I can't pass the GraphResult, as it does not feature any way to recreate the request. GraphResponse contains all the info needed in theory, but since a 429 will lead to a GraphFailure, I dont get one. And finally, GraphFailure does also not contain the needed information like url to retry the request. So, does anyone have hints how to handle retries in a somewhat generic way where I dont have to copy paste a bunch of code everywhere i make a request? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 7 replies
-
Yeah so there are a couple of reasons why the functionality with The first is that it has to handle both blocking and asynchronous request types and it does this by using a generic value: The second reason gets to the point you bring up which is that the I think what your getting at though is important. We don't necessarily want to force having to rewrite a request every time they need to perform the same request. A simple solution from the callers perspective is just to write functions that call the same request. But that would just add more work on the caller. Changes to what is returned in the To be honest I think in some ways a retry-able request object is more reliable because it contains the exact information you need without having to recreate the same request. And I have wanted something like this for a while as well. |
Beta Was this translation helpful? Give feedback.
-
I mentioned this in another discussion as well but wanted to just add here that I gladly welcome contributions to this or any other ticket as well if anyone would like too. Not a requirement at all but if you do want to contribute I can also help answer any questions. |
Beta Was this translation helpful? Give feedback.
-
Filed ticket. : #363 Thanks for the feedback! |
Beta Was this translation helpful? Give feedback.
-
So one thing i can be up with that might be a reasonable way to handle this would be a send_with_retry function implemented on IntoResponse (analogue to the send function) that could be configured how and when to retry a request. The configuration could be done through a builder pattern struct that would contain the number of retires, a list of status codes to retry on, and potentially a Fn(GraphResult) -> bool (or maybe GraphResponse or even T) with a default implementation that just retries 1 or 2 times on any GraphError. I'll see if I can code a pull request together, though I'm not promising anything. |
Beta Was this translation helpful? Give feedback.
-
Following the release of the 1.0 version I would like to add my 2 cents. I have been using the tokio-retry crate to implement retries, either from 429 or incorrect responses from Azure (yes, it happens sometimes). match Retry::spawn((retry_strategy.clone()), || async {
client
.reports()
.get_office_365_services_user_counts_by_period(period)
.send().await.map_err(|e| SimpleError::from(e))?
.text()
.await.map_err(|e| SimpleError::from(e))
}).await {
Ok(report) => {
// cut
}
Err(e) => { error!( "Error while processing {} : {:?}" , (format!("office365_services_user_counts_{}", period).as_str()) , e ) }
} It's a bit cumbersome, because of the (new) need to have a mutable ref to client if you need to switch from v1 and beta often like I do (not possible in an async block) and the need to encapsulate error now that there is multiple function that can fail on the same chain. I can take a look to implement an internal retry if I can find time for that. |
Beta Was this translation helpful? Give feedback.
Filed ticket. : #363
Thanks for the feedback!