#[cfg(feature = "rt")]
mod gate {
use std::{sync::mpsc, time::Duration};
#[derive(Debug)]
enum MyError {}
use qsu::{
rt::{
Demise, InitCtx, RunCtx, RunEnv, ServiceHandler, SrvAppRt, SvcEvt,
TermCtx, UserSig
},
tracing
};
struct InitData {
name: String,
value: u32
}
struct TermData {
name: String,
value: u32
}
struct AnotherTermData {
name: String,
value: u32
}
struct MyService {
rx_term: mpsc::Receiver<()>
}
impl ServiceHandler for MyService {
type AppErr = MyError;
fn init(&mut self, ictx: &mut InitCtx) -> Result<(), Self::AppErr> {
tracing::info!("Running ServiceHandler::init()");
let id = ictx.take::<InitData>().unwrap();
assert_eq!(id.name, "hello");
assert_eq!(id.value, 42);
log::info!("init passthrough name={}, value={}", id.name, id.value);
let atd = AnotherTermData {
name: "extra bye".to_string(),
value: 23
};
ictx.term_passthrough(atd);
Ok(())
}
fn run(&mut self, _re: &RunEnv) -> Result<(), Self::AppErr> {
tracing::info!("Running ServiceHandler::run()");
tracing::info!("Wait for termination event for up to 4 seconds ..");
let _ = self.rx_term.recv_timeout(Duration::from_secs(4));
Ok(())
}
fn shutdown(&mut self, tctx: &mut TermCtx) -> Result<(), Self::AppErr> {
tracing::info!("Running ServiceHandler::shutdown()");
let td = tctx.take::<TermData>().unwrap();
assert_eq!(td.name, "bye");
assert_eq!(td.value, 17);
log::info!("term passthrough name={}, value={}", td.name, td.value);
let atd = tctx.take::<AnotherTermData>().unwrap();
assert_eq!(atd.name, "extra bye");
assert_eq!(atd.value, 23);
log::info!(
"another term passthrough name={}, value={}",
atd.name,
atd.value
);
Ok(())
}
}
pub fn main() {
let svcname = qsu::default_service_name().unwrap();
let (tx, rx) = mpsc::channel::<()>();
let svcevt_handler = move |msg| match msg {
SvcEvt::Shutdown(demise) => {
tracing::debug!("Shutdown event received");
match demise {
Demise::Interrupted => {
tracing::info!("Service application was interrupted");
}
Demise::Terminated => {
tracing::info!("Service application was terminated");
}
Demise::ReachedEnd => {
tracing::info!("Service application reached its end");
}
}
tx.send(()).unwrap();
}
SvcEvt::User(us) => match us {
UserSig::Sig1 => {
log::info!("User signal 1");
}
UserSig::Sig2 => {
log::info!("User signal 2");
}
},
_ => {}
};
let svcrt = MyService { rx_term: rx };
let apprt = SrvAppRt::Sync {
svcevt_handler: Box::new(svcevt_handler),
rt_handler: Box::new(svcrt)
};
let id = InitData {
name: String::from("hello"),
value: 42
};
let td = TermData {
name: String::from("bye"),
value: 17
};
let rctx = RunCtx::new(&svcname)
.init_passthrough(id)
.term_passthrough(td);
rctx.run(apprt).unwrap();
}
}
fn main() {
#[cfg(feature = "rt")]
gate::main();
#[cfg(not(feature = "rt"))]
println!("simplesync example requires the rt feature");
}