I have a util struct use to retry a function multiple times until it returns an Ok
result. There's some Builder methods to configure wait time and retry times, and a function called run
that takes in the function to retry.
I have a problem with either the function signature or the return of the lambda method and the compiler error isn't helping me much.
Here is the function in question. The plan is to take in a parameter that is a function that returns a Future. The Future must return a Result of some kind to see if it should be retried or not. This is an async function so that I don't block in-between retries. There might be a few errors in the retry logic but it doesn't matter for now.
pub async fn run_async<T, E, F>(self, func: impl Fn() -> F) -> Result<T, RetryError>
where
F: Future<Output = Result<T, E>>,
E: std::fmt::Debug,
{
let mut current: usize = 0;
loop {
let res: Result<T, E> = func().await;
if res.is_ok() {
return Ok(res.unwrap());
} else {
if self.count == 0 {
if let Some(wait) = self.waittime.as_ref() {
tokio::time::delay_for(*wait).await;
} else {
tokio::task::yield_now().await;
}
continue;
} else {
current += 1;
if current > self.count {
return Err(RetryError {});
}
}
}
}
}
I'm calling the methods like this. I'm using future::ok
from the Futures crate. I need this in case I need to retry a method that isn't async itself. If I return the return of a function that returns a impl core::future::future::Future
the function will compile correctly. But if I return a future from the Futures crate (such as future::ok
) it complains about missing type annotations.
let retry_future = Retry::new()
.max_tries(5)
.wait(Duration::from_secs(2))
.run_async( || {
// Sample use case. Does not work.
return future::ok(1);
});
Error is :
error[E0282]: type annotations needed
--> src/main.rs:9:10
|
6 | let retry_future = Retry::new()
| ------------ consider giving `retry_future` a type
...
9 | .run_async( || {
| ^^^^^^^^^ cannot infer type for type parameter `E` declared on the associated function `run_async`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.
error: could not compile `playground`.
I put the sample code in here. I have no idea how to fix this error. The message isn't super helpful. I tried adding type to retry_future but no matter what type I put I can't get the correct one.
Can anyone help me on this ?