Add basic retry policies to zebra-network.

This should be removed when https://github.com/tower-rs/tower/pull/414 lands
but is good enough for our purposes for now.
This commit is contained in:
Henry de Valence 2020-02-11 10:06:38 -08:00 committed by Deirdre Connolly
parent 5191b9d1d5
commit abcc0a6773
2 changed files with 63 additions and 0 deletions

View File

@ -52,6 +52,7 @@ mod config;
mod constants;
mod meta_addr;
mod network;
mod policies;
mod peer;
mod peer_set;
mod protocol;
@ -62,6 +63,7 @@ pub use crate::{
config::Config,
peer_set::init,
protocol::internal::{Request, Response},
policies::{RetryErrors, RetryLimit},
};
/// Types used in the definition of [`Request`] and [`Response`] messages.

View File

@ -0,0 +1,61 @@
use tower::retry::Policy;
use futures::future;
/// A very basic retry policy with a limited number of retry attempts.
///
/// XXX Remove this when https://github.com/tower-rs/tower/pull/414 lands.
#[derive(Clone, Debug)]
pub struct RetryLimit {
remaining_tries: usize,
}
impl RetryLimit {
/// Create a policy with the given number of retry attempts.
pub fn new(retry_attempts: usize) -> Self {
RetryLimit {
remaining_tries: retry_attempts,
}
}
}
impl<Req: Clone, Res, E> Policy<Req, Res, E> for RetryLimit {
type Future = future::Ready<Self>;
fn retry(&self, _: &Req, result: Result<&Res, &E>) -> Option<Self::Future> {
if result.is_err() {
if self.remaining_tries > 0 {
Some(future::ready(RetryLimit {
remaining_tries: self.remaining_tries - 1,
}))
} else {
None
}
} else {
None
}
}
fn clone_request(&self, req: &Req) -> Option<Req> {
Some(req.clone())
}
}
/// A very basic retry policy that always retries failed requests.
///
/// XXX remove this when https://github.com/tower-rs/tower/pull/414 lands.
#[derive(Clone, Debug)]
pub struct RetryErrors;
impl<Req: Clone, Res, E> Policy<Req, Res, E> for RetryErrors {
type Future = future::Ready<Self>;
fn retry(&self, _: &Req, result: Result<&Res, &E>) -> Option<Self::Future> {
if result.is_err() {
Some(future::ready(RetryErrors))
} else {
None
}
}
fn clone_request(&self, req: &Req) -> Option<Req> {
Some(req.clone())
}
}