Alex Mikhalev
4 years ago
4 changed files with 119 additions and 55 deletions
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
use crate::{ |
||||
mqtt_interface::MqttInterface, |
||||
section_runner::{SectionEvent, SectionEventRecv}, |
||||
}; |
||||
use tokio::{select, sync::broadcast, task::JoinHandle}; |
||||
use tracing::trace; |
||||
|
||||
pub struct UpdateListener { |
||||
mqtt_interface: MqttInterface, |
||||
running: bool, |
||||
} |
||||
|
||||
impl UpdateListener { |
||||
pub fn start( |
||||
section_events: SectionEventRecv, |
||||
mqtt_interface: MqttInterface, |
||||
) -> JoinHandle<()> { |
||||
let update_listener = UpdateListener { |
||||
mqtt_interface, |
||||
running: true, |
||||
}; |
||||
tokio::spawn(update_listener.run(section_events)) |
||||
} |
||||
|
||||
async fn handle_section_event( |
||||
&mut self, |
||||
event: Result<SectionEvent, broadcast::RecvError>, |
||||
) -> eyre::Result<()> { |
||||
let event = match event { |
||||
Err(broadcast::RecvError::Closed) => { |
||||
trace!("section events channel closed"); |
||||
self.running = false; |
||||
return Ok(()); |
||||
} |
||||
e => e, |
||||
}?; |
||||
if let Some((sec_id, state)) = match event { |
||||
SectionEvent::RunStart(_, sec) | SectionEvent::RunUnpause(_, sec) => { |
||||
Some((sec.id, true)) |
||||
} |
||||
SectionEvent::RunFinish(_, sec) |
||||
| SectionEvent::RunPause(_, sec) |
||||
| SectionEvent::RunCancel(_, sec) => Some((sec.id, false)), |
||||
SectionEvent::RunnerPause | SectionEvent::RunnerUnpause => None, |
||||
} { |
||||
self.mqtt_interface |
||||
.publish_section_state(sec_id, state) |
||||
.await?; |
||||
} |
||||
Ok(()) |
||||
} |
||||
|
||||
pub async fn run(mut self, mut section_events: SectionEventRecv) { |
||||
while self.running { |
||||
let result = select! { |
||||
section_event = section_events.recv() => { |
||||
self.handle_section_event(section_event).await |
||||
} |
||||
}; |
||||
result.expect("error in update_listener task"); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue