#[cfg(all(feature = "rt", feature = "tokio"))] mod gate { use std::time::Duration; use tokio::{sync::mpsc, time}; use qsu::{ async_trait, rt::{ InitCtx, RunCtx, RunEnv, SrvAppRt, SvcEvt, TermCtx, TokioServiceHandler, UserSig }, tracing }; #[derive(Debug)] enum MyError {} struct MyService { rx_term: mpsc::UnboundedReceiver<()> } #[async_trait] impl TokioServiceHandler for MyService { type AppErr = MyError; async fn init(&mut self, ictx: InitCtx) -> Result<(), Self::AppErr> { tracing::info!("Running TokioServiceHandler::init()"); ictx.report(Some("Initializing service handler".into())); // .. do initialization here .. ictx.report(Some("Finalized service handler initialization".into())); Ok(()) } async fn run(&mut self, _re: &RunEnv) -> Result<(), Self::AppErr> { tracing::info!("Running TokioServiceHandler::run()"); tracing::info!("Wait for termination event for up to 4 seconds .."); tokio::select! { _ = self.rx_term.recv() => { tracing::info!("Got kill signal from svc"); } () = time::sleep(Duration::from_secs(4)) => { tracing::info!("Got timeout"); } } Ok(()) } async fn shutdown(&mut self, tctx: TermCtx) -> Result<(), Self::AppErr> { tracing::info!("Running TokioServiceHandler::shutdown()"); tctx.report(Some("Terminating service handler".into())); // .. do termination here .. tctx.report(Some("Finalized service handler termination".into())); Ok(()) } } pub fn main() { let svcname = qsu::default_service_name().unwrap(); // Channel used to signal termination from service event handler to main // application let (tx, rx) = mpsc::unbounded_channel::<()>(); // Service event handler let svcevt_handler = move |msg| match msg { SvcEvt::Shutdown(_) => { tracing::debug!("Shutdown event from service subsystem"); // Once a Shutdown or Termination event has been received, signal to // the main service callback to terminate. let _ = tx.send(()); } SvcEvt::User(us) => match us { UserSig::Sig1 => { log::info!("User signal 1"); } UserSig::Sig2 => { log::info!("User signal 2"); } }, _ => {} }; // Set up main service runtime handler let svcrt = MyService { rx_term: rx }; // Define service application runtime components let apprt = SrvAppRt::Tokio { rtbldr: None, svcevt_handler: Box::new(svcevt_handler), rt_handler: Box::new(svcrt) }; // Launch service let rctx = RunCtx::new(&svcname); rctx.run(apprt).unwrap(); } } fn main() { #[cfg(all(feature = "rt", feature = "tokio"))] gate::main(); #[cfg(not(all(feature = "rt", feature = "tokio")))] println!("simpletokio example requires the rt and tokio features"); } // vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :