I have implemented this RateLimiter
Struct
:
pub struct RateLimiter<S, T>
where
S: Service<T>,
S::Response: Send + 'static,
S::Error: Into<APIError> + Into<Box<dyn StdError + Send + Sync + 'static>> + Send + Sync + 'static,
S::Future: Send + 'static,
T: Send + 'static,
{
service: Buffer<T, ResponseFuture<<S as Service<T>>::Future>>,
}
impl<S, T> RateLimiter<S, T>
where
S: Service<T> + Send + 'static,
S::Response: Send + 'static,
S::Error: Into<APIError> + Into<Box<dyn StdError + Send + Sync + 'static>> + Send + Sync + 'static,
S::Future: Send + 'static,
T: Send + 'static,
{
pub fn new(service: S, rate_limit: usize, buffer_size: usize, concurrency_limit: usize) -> Result<Self, APIError> {
let rate_limit_u64: u64 = rate_limit
.try_into()
.map_err(|_| APIError::Other("Invalid rate limit value".to_string()))?;
let rate_limited_service: Buffer<T, ResponseFuture<<S as Service<T>>::Future>> = ServiceBuilder::new()
.buffer(buffer_size)
.concurrency_limit(concurrency_limit)
.rate_limit(rate_limit_u64, Duration::from_secs(1))
.service(service);
Ok(RateLimiter {
service: rate_limited_service,
})
}
pub async fn call(&mut self, request: T) -> Result<S::Response, APIError> {
self.service.call(request).await.map_err(|e| APIError::from(e))
}
}
I want to add retry
capability to it in case of failure of a request
. How can I achieve this using tower
?
I’ve spent quite a bit of time experimenting with different approaches to add retry capability to my service using Tower, but unfortunately, all my attempts have failed.
2