trillium_server_common/
server_handle.rs1use crate::Runtime;
2use async_cell::sync::AsyncCell;
3use std::{cell::OnceCell, future::IntoFuture, net::SocketAddr, sync::Arc};
4use swansong::{ShutdownCompletion, Swansong};
5use trillium_http::HttpContext;
6
7#[derive(Clone, Debug)]
11pub struct ServerHandle {
12 pub(crate) swansong: Swansong,
13 pub(crate) context: Arc<AsyncCell<Arc<HttpContext>>>,
14 pub(crate) received_context: OnceCell<Arc<HttpContext>>,
15 pub(crate) runtime: Runtime,
16}
17
18#[derive(Debug)]
23pub struct BoundInfo(Arc<HttpContext>);
24
25impl BoundInfo {
26 pub fn shared_state<T: Send + Sync + 'static>(&self) -> Option<&T> {
28 self.0.shared_state().get()
29 }
30
31 pub fn tcp_socket_addr(&self) -> Option<&SocketAddr> {
33 self.shared_state()
34 }
35
36 pub fn listeners(&self) -> &[trillium::Listener] {
39 self.shared_state::<trillium::Listeners>()
40 .map_or(&[], |l| &l.0)
41 }
42
43 pub fn url(&self) -> Option<&url::Url> {
45 self.shared_state()
46 }
47
48 #[cfg(unix)]
50 pub fn unix_socket_addr(&self) -> Option<&std::os::unix::net::SocketAddr> {
51 self.shared_state()
52 }
53
54 pub fn context(&self) -> Arc<HttpContext> {
56 self.0.clone()
57 }
58}
59
60impl ServerHandle {
61 pub async fn info(&self) -> BoundInfo {
63 if let Some(context) = self.received_context.get().cloned() {
64 return BoundInfo(context);
65 }
66 let arc_context = self.context.get().await;
67 let context = self.received_context.get_or_init(|| arc_context);
68
69 BoundInfo(Arc::clone(context))
70 }
71
72 pub fn shut_down(&self) -> ShutdownCompletion {
74 self.swansong.shut_down()
75 }
76
77 pub fn swansong(&self) -> Swansong {
79 self.swansong.clone()
80 }
81
82 pub fn runtime(&self) -> Runtime {
84 self.runtime.clone()
85 }
86
87 pub fn block(self) {
89 self.into_future().block()
90 }
91}
92
93impl IntoFuture for ServerHandle {
94 type IntoFuture = ShutdownCompletion;
95 type Output = ();
96
97 fn into_future(self) -> Self::IntoFuture {
98 self.swansong.into_future()
99 }
100}