use std::sync::Arc;
use std::time::Duration;
use crate::device::DeviceBackend;
use crate::printer::PrinterRegistry;
const POLL_INTERVAL: Duration = Duration::from_secs(30);
pub fn spawn(
backend: Arc<dyn DeviceBackend>,
registry: PrinterRegistry,
) -> tokio::task::JoinHandle<()> {
let interval = std::env::var("IPP_PRINTER_APP_POLL_SECS")
.ok()
.and_then(|s| s.parse().ok())
.map(Duration::from_secs)
.unwrap_or(POLL_INTERVAL);
tokio::spawn(async move {
let mut ticker = tokio::time::interval(interval);
ticker.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
ticker.tick().await; loop {
ticker.tick().await;
poll_once(backend.as_ref(), ®istry).await;
}
})
}
async fn poll_once(backend: &dyn DeviceBackend, registry: &PrinterRegistry) {
use crate::printer::IppPrinterState;
let configs: Vec<_> = {
let g = registry.read();
g.iter()
.filter(|r| r.state == IppPrinterState::Idle)
.map(|r| r.config.clone())
.collect()
};
for cfg in configs {
let reasons = tokio::task::block_in_place(|| backend.poll_status(&cfg));
if let Some(reasons) = reasons {
let mut g = registry.write();
if let Some(rec) = g.iter_mut().find(|r| r.config.name == cfg.name) {
if rec.reasons != reasons {
log::debug!(
"status: {} reasons {:?} -> {:?}",
cfg.name,
rec.reasons,
reasons
);
rec.reasons = reasons;
}
}
}
}
}