use crate::request::{FromRequest, Outcome, Request}; use tokio::sync::mpsc; /// # Example /// /// ```rust /// # #![feature(proc_macro_hygiene)] /// # #[macro_use] extern crate rocket; /// # /// use rocket::shutdown::ShutdownHandle; /// /// #[get("/shutdown")] /// fn shutdown(handle: ShutdownHandle) -> &'static str { /// handle.shutdown(); /// "Shutting down..." /// } /// /// fn main() { /// # if false { /// rocket::ignite() /// .mount("/", routes![shutdown]) /// .launch() /// .expect("server failed unexpectedly"); /// # } /// } /// ``` #[derive(Debug, Clone)] pub struct ShutdownHandle(pub(crate) mpsc::Sender<()>); impl ShutdownHandle { /// Notify Rocket to shut down gracefully. #[inline] pub fn shutdown(mut self) { // Intentionally ignore any error, as the only scenarios this can happen // is sending too many shutdown requests or we're already shut down. let _ = self.0.try_send(()); info!("Server shutdown requested, waiting for all pending requests to finish."); } } impl FromRequest<'_, '_> for ShutdownHandle { type Error = std::convert::Infallible; #[inline] fn from_request(request: &Request<'_>) -> Outcome { Outcome::Success(request.state.managed.get::().0.clone()) } } // Use this type in managed state to avoid placing `ShutdownHandle` in it. pub(crate) struct ShutdownHandleManaged(pub ShutdownHandle);