ipp_printer_app/
status.rs1use std::sync::Arc;
10use std::time::Duration;
11
12use crate::device::DeviceBackend;
13use crate::printer::PrinterRegistry;
14
15const POLL_INTERVAL: Duration = Duration::from_secs(30);
17
18pub fn spawn(
21 backend: Arc<dyn DeviceBackend>,
22 registry: PrinterRegistry,
23) -> tokio::task::JoinHandle<()> {
24 let interval = std::env::var("IPP_PRINTER_APP_POLL_SECS")
25 .ok()
26 .and_then(|s| s.parse().ok())
27 .map(Duration::from_secs)
28 .unwrap_or(POLL_INTERVAL);
29
30 tokio::spawn(async move {
31 let mut ticker = tokio::time::interval(interval);
34 ticker.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
35 ticker.tick().await; loop {
37 ticker.tick().await;
38 poll_once(backend.as_ref(), ®istry).await;
39 }
40 })
41}
42
43async fn poll_once(backend: &dyn DeviceBackend, registry: &PrinterRegistry) {
44 use crate::printer::IppPrinterState;
45 let configs: Vec<_> = {
48 let g = registry.read();
49 g.iter()
50 .filter(|r| r.state == IppPrinterState::Idle)
51 .map(|r| r.config.clone())
52 .collect()
53 };
54
55 for cfg in configs {
56 let reasons = tokio::task::block_in_place(|| backend.poll_status(&cfg));
59 if let Some(reasons) = reasons {
60 let mut g = registry.write();
61 if let Some(rec) = g.iter_mut().find(|r| r.config.name == cfg.name) {
62 if rec.reasons != reasons {
63 log::debug!(
64 "status: {} reasons {:?} -> {:?}",
65 cfg.name,
66 rec.reasons,
67 reasons
68 );
69 rec.reasons = reasons;
70 }
71 }
72 }
73 }
74}