|
|
@ -1,5 +1,6 @@ |
|
|
|
use crate::{ |
|
|
|
use crate::{ |
|
|
|
mqtt_interface::MqttInterface, |
|
|
|
mqtt_interface::MqttInterface, |
|
|
|
|
|
|
|
program_runner::{ProgramEvent, ProgramEventRecv}, |
|
|
|
section_runner::{SectionEvent, SectionEventRecv}, |
|
|
|
section_runner::{SectionEvent, SectionEventRecv}, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use tokio::{ |
|
|
|
use tokio::{ |
|
|
@ -11,6 +12,8 @@ use tracing::{trace, trace_span, warn}; |
|
|
|
use tracing_futures::Instrument; |
|
|
|
use tracing_futures::Instrument; |
|
|
|
|
|
|
|
|
|
|
|
struct UpdateListenerTask { |
|
|
|
struct UpdateListenerTask { |
|
|
|
|
|
|
|
section_events: SectionEventRecv, |
|
|
|
|
|
|
|
program_events: ProgramEventRecv, |
|
|
|
mqtt_interface: MqttInterface, |
|
|
|
mqtt_interface: MqttInterface, |
|
|
|
running: bool, |
|
|
|
running: bool, |
|
|
|
} |
|
|
|
} |
|
|
@ -48,37 +51,62 @@ impl UpdateListenerTask { |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async fn run_impl(&mut self, mut section_events: SectionEventRecv) -> eyre::Result<()> { |
|
|
|
async fn handle_program_event( |
|
|
|
|
|
|
|
&mut self, |
|
|
|
|
|
|
|
event: Result<ProgramEvent, broadcast::RecvError>, |
|
|
|
|
|
|
|
) -> eyre::Result<()> { |
|
|
|
|
|
|
|
let event = match event { |
|
|
|
|
|
|
|
Ok(ev) => ev, |
|
|
|
|
|
|
|
Err(broadcast::RecvError::Closed) => { |
|
|
|
|
|
|
|
trace!("section events channel closed"); |
|
|
|
|
|
|
|
self.running = false; |
|
|
|
|
|
|
|
return Ok(()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Err(broadcast::RecvError::Lagged(n)) => { |
|
|
|
|
|
|
|
warn!("section events lagged by {}", n); |
|
|
|
|
|
|
|
return Ok(()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
let (program_id, running) = match event { |
|
|
|
|
|
|
|
ProgramEvent::RunStart(prog) => (prog.id, true), |
|
|
|
|
|
|
|
ProgramEvent::RunFinish(prog) | ProgramEvent::RunCancel(prog) => (prog.id, false), |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
self.mqtt_interface |
|
|
|
|
|
|
|
.publish_program_running(program_id, running) |
|
|
|
|
|
|
|
.await?; |
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async fn run_impl(&mut self) -> eyre::Result<()> { |
|
|
|
while self.running { |
|
|
|
while self.running { |
|
|
|
select! { |
|
|
|
select! { |
|
|
|
section_event = section_events.recv() => { |
|
|
|
section_event = self.section_events.recv() => { |
|
|
|
self.handle_section_event(section_event).await? |
|
|
|
self.handle_section_event(section_event).await? |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
program_event = self.program_events.recv() => { |
|
|
|
|
|
|
|
self.handle_program_event(program_event).await? |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async fn run_or_quit( |
|
|
|
async fn run_or_quit(mut self, mut quit_rx: oneshot::Receiver<()>) -> eyre::Result<()> { |
|
|
|
mut self, |
|
|
|
|
|
|
|
mut quit_rx: oneshot::Receiver<()>, |
|
|
|
|
|
|
|
section_events: SectionEventRecv, |
|
|
|
|
|
|
|
) -> eyre::Result<()> { |
|
|
|
|
|
|
|
select! { |
|
|
|
select! { |
|
|
|
_ = &mut quit_rx => { |
|
|
|
_ = &mut quit_rx => { |
|
|
|
self.running = false; |
|
|
|
self.running = false; |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
res = self.run_impl(section_events) => { |
|
|
|
res = self.run_impl() => { |
|
|
|
res |
|
|
|
res |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async fn run(self, quit_rx: oneshot::Receiver<()>, section_events: SectionEventRecv) { |
|
|
|
async fn run(self, quit_rx: oneshot::Receiver<()>) { |
|
|
|
let span = trace_span!("update_listener task"); |
|
|
|
let span = trace_span!("update_listener task"); |
|
|
|
|
|
|
|
|
|
|
|
self.run_or_quit(quit_rx, section_events) |
|
|
|
self.run_or_quit(quit_rx) |
|
|
|
.instrument(span) |
|
|
|
.instrument(span) |
|
|
|
.await |
|
|
|
.await |
|
|
|
.expect("error in UpdateListenerTask"); |
|
|
|
.expect("error in UpdateListenerTask"); |
|
|
@ -91,13 +119,19 @@ pub struct UpdateListener { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl UpdateListener { |
|
|
|
impl UpdateListener { |
|
|
|
pub fn start(section_events: SectionEventRecv, mqtt_interface: MqttInterface) -> Self { |
|
|
|
pub fn start( |
|
|
|
|
|
|
|
section_events: SectionEventRecv, |
|
|
|
|
|
|
|
program_events: ProgramEventRecv, |
|
|
|
|
|
|
|
mqtt_interface: MqttInterface, |
|
|
|
|
|
|
|
) -> Self { |
|
|
|
let task = UpdateListenerTask { |
|
|
|
let task = UpdateListenerTask { |
|
|
|
|
|
|
|
section_events, |
|
|
|
|
|
|
|
program_events, |
|
|
|
mqtt_interface, |
|
|
|
mqtt_interface, |
|
|
|
running: true, |
|
|
|
running: true, |
|
|
|
}; |
|
|
|
}; |
|
|
|
let (quit_tx, quit_rx) = oneshot::channel(); |
|
|
|
let (quit_tx, quit_rx) = oneshot::channel(); |
|
|
|
let join_handle = tokio::spawn(task.run(quit_rx, section_events)); |
|
|
|
let join_handle = tokio::spawn(task.run(quit_rx)); |
|
|
|
Self { |
|
|
|
Self { |
|
|
|
quit_tx, |
|
|
|
quit_tx, |
|
|
|
join_handle, |
|
|
|
join_handle, |
|
|
|