1
2use tower::Service;
3use std::task::{Context, Poll};
4use std::sync::Arc;
5use tokio::sync::Mutex;
6use crate::policy::Policy;
7
8pub struct DoOverService<S, P> {
9 inner: Arc<Mutex<S>>,
10 policy: P,
11}
12
13impl<S, P> DoOverService<S, P> {
14 pub fn new(inner: S, policy: P) -> Self {
15 Self {
16 inner: Arc::new(Mutex::new(inner)),
17 policy,
18 }
19 }
20}
21
22impl<S, P, Req, Res, Err> Service<Req> for DoOverService<S, P>
23where
24 S: Service<Req, Response = Res, Error = Err> + Send + 'static,
25 S::Future: Send,
26 P: Policy<Err> + Send + Sync + 'static + Clone,
27 Req: Send + Sync + Clone + 'static,
28 Res: Send + 'static,
29 Err: Send + 'static,
30{
31 type Response = Res;
32 type Error = Err;
33 type Future = futures::future::BoxFuture<'static, Result<Res, Err>>;
34
35 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
36 Poll::Ready(Ok(()))
38 }
39
40 fn call(&mut self, req: Req) -> Self::Future {
41 let inner = Arc::clone(&self.inner);
42 let policy = self.policy.clone();
43
44 Box::pin(async move {
45 policy.execute(|| async {
46 let mut svc = inner.lock().await;
47 svc.call(req.clone()).await
48 }).await
49 })
50 }
51}