mod argp;
mod err;
mod procres;
use std::{
thread,
time::{Duration, Instant}
};
use tokio::sync::mpsc;
use qsu::{
argp::ArgParser,
rt::{InitCtx, RunEnv, ServiceHandler, SrvAppRt, SvcEvt, TermCtx}
};
use err::Error;
use procres::ProcRes;
struct MyService {
rx: mpsc::UnboundedReceiver<SvcEvt>
}
impl ServiceHandler for MyService {
type AppErr = Error;
fn init(&mut self, ictx: &mut InitCtx) -> Result<(), Self::AppErr> {
ictx.report(Some("Entered init"));
Ok(())
}
fn run(&mut self, _re: &RunEnv) -> Result<(), Self::AppErr> {
const SECS: u64 = 30;
let mut last_dump = Instant::now()
.checked_sub(Duration::from_secs(SECS))
.unwrap();
loop {
if last_dump.elapsed() > Duration::from_secs(SECS) {
log::error!("error");
log::warn!("warn");
log::info!("info");
log::debug!("debug");
log::trace!("trace");
tracing::error!("error");
tracing::warn!("warn");
tracing::info!("info");
tracing::debug!("debug");
tracing::trace!("trace");
last_dump = Instant::now();
}
match self.rx.try_recv() {
Ok(SvcEvt::Shutdown(_)) => {
tracing::info!("Service application shutdown");
break;
}
Ok(SvcEvt::ReloadConf) => {
tracing::info!(
"The service subsystem requested that the application reload its \
configuration"
);
}
_ => {}
}
thread::sleep(std::time::Duration::from_secs(1));
}
Ok(())
}
fn shutdown(&mut self, tctx: &mut TermCtx) -> Result<(), Self::AppErr> {
tctx.report(Some("Entered shutdown"));
Ok(())
}
}
fn main() -> ProcRes {
ProcRes::into(main2().into())
}
fn main2() -> Result<(), Error> {
let svcname = qsu::default_service_name()
.expect("Unable to determine default service name");
let bldr = Box::new(|| {
let (tx, rx) = mpsc::unbounded_channel();
SrvAppRt::Sync {
svcevt_handler: Box::new(move |msg| {
tx.send(msg).unwrap();
}),
rt_handler: Box::new(MyService { rx })
}
});
let mut argsproc = argp::AppArgsProc { bldr };
let ap =
ArgParser::new(&svcname, &mut argsproc).regsvc_proc(|mut regsvc| {
if regsvc.description.is_none() {
regsvc
.description_ref("A sync server that says hello every 30 seconds");
}
regsvc
});
ap.proc()?;
Ok(())
}