rpcs.rs 892 B

1234567891011121314151617181920212223242526272829303132
  1. use std::future::Future;
  2. use std::time::Duration;
  3. pub async fn retry_rpc<'a, Func, Fut, T>(
  4. max_retry: usize,
  5. deadline: Duration,
  6. mut task_gen: Func,
  7. ) -> std::io::Result<T>
  8. where
  9. Fut: Future<Output = std::io::Result<T>> + Send + 'a,
  10. Func: FnMut(usize) -> Fut,
  11. {
  12. for i in 0..max_retry {
  13. if i != 0 {
  14. tokio::time::sleep(Duration::from_millis((1 << i) * 10)).await;
  15. }
  16. // Not timed-out.
  17. #[allow(clippy::collapsible_match)]
  18. if let Ok(reply) = tokio::time::timeout(deadline, task_gen(i)).await {
  19. // And no error
  20. if let Ok(reply) = reply {
  21. return Ok(reply);
  22. }
  23. }
  24. }
  25. Err(std::io::Error::new(
  26. std::io::ErrorKind::TimedOut,
  27. format!("Timed out after {} retries", max_retry),
  28. ))
  29. }
  30. pub const RPC_DEADLINE: Duration = Duration::from_secs(2);