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