1 use std::fmt;
2 use std::future::Future;
3 use std::pin::Pin;
4 use std::sync::Arc;
5 
6 use crate::body::{Body, HttpBody};
7 use crate::proto::h2::server::H2Stream;
8 use crate::server::conn::spawn_all::{NewSvcTask, Watcher};
9 use crate::service::HttpService;
10 
11 /// An executor of futures.
12 pub trait Executor<Fut> {
13     /// Place the future into the executor to be run.
execute(&self, fut: Fut)14     fn execute(&self, fut: Fut);
15 }
16 
17 pub trait H2Exec<F, B: HttpBody>: Clone {
execute_h2stream(&mut self, fut: H2Stream<F, B>)18     fn execute_h2stream(&mut self, fut: H2Stream<F, B>);
19 }
20 
21 pub trait NewSvcExec<I, N, S: HttpService<Body>, E, W: Watcher<I, S, E>>: Clone {
execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>)22     fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>);
23 }
24 
25 pub type BoxSendFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
26 
27 // Either the user provides an executor for background tasks, or we use
28 // `tokio::spawn`.
29 #[derive(Clone)]
30 pub enum Exec {
31     Default,
32     Executor(Arc<dyn Executor<BoxSendFuture> + Send + Sync>),
33 }
34 
35 // ===== impl Exec =====
36 
37 impl Exec {
execute<F>(&self, fut: F) where F: Future<Output = ()> + Send + 'static,38     pub(crate) fn execute<F>(&self, fut: F)
39     where
40         F: Future<Output = ()> + Send + 'static,
41     {
42         match *self {
43             Exec::Default => {
44                 #[cfg(feature = "tcp")]
45                 {
46                     tokio::task::spawn(fut);
47                 }
48                 #[cfg(not(feature = "tcp"))]
49                 {
50                     // If no runtime, we need an executor!
51                     panic!("executor must be set")
52                 }
53             }
54             Exec::Executor(ref e) => {
55                 e.execute(Box::pin(fut));
56             }
57         }
58     }
59 }
60 
61 impl fmt::Debug for Exec {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result62     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63         f.debug_struct("Exec").finish()
64     }
65 }
66 
67 impl<F, B> H2Exec<F, B> for Exec
68 where
69     H2Stream<F, B>: Future<Output = ()> + Send + 'static,
70     B: HttpBody,
71 {
execute_h2stream(&mut self, fut: H2Stream<F, B>)72     fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
73         self.execute(fut)
74     }
75 }
76 
77 impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for Exec
78 where
79     NewSvcTask<I, N, S, E, W>: Future<Output = ()> + Send + 'static,
80     S: HttpService<Body>,
81     W: Watcher<I, S, E>,
82 {
execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>)83     fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) {
84         self.execute(fut)
85     }
86 }
87 
88 // ==== impl Executor =====
89 
90 impl<E, F, B> H2Exec<F, B> for E
91 where
92     E: Executor<H2Stream<F, B>> + Clone,
93     H2Stream<F, B>: Future<Output = ()>,
94     B: HttpBody,
95 {
execute_h2stream(&mut self, fut: H2Stream<F, B>)96     fn execute_h2stream(&mut self, fut: H2Stream<F, B>) {
97         self.execute(fut)
98     }
99 }
100 
101 impl<I, N, S, E, W> NewSvcExec<I, N, S, E, W> for E
102 where
103     E: Executor<NewSvcTask<I, N, S, E, W>> + Clone,
104     NewSvcTask<I, N, S, E, W>: Future<Output = ()>,
105     S: HttpService<Body>,
106     W: Watcher<I, S, E>,
107 {
execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>)108     fn execute_new_svc(&mut self, fut: NewSvcTask<I, N, S, E, W>) {
109         self.execute(fut)
110     }
111 }
112