Implement publishing program next run
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
da3662c3df
commit
9f37cd2805
@ -20,6 +20,7 @@ pub enum ProgramEvent {
|
||||
RunStart(ProgramRef),
|
||||
RunFinish(ProgramRef),
|
||||
RunCancel(ProgramRef),
|
||||
NextRun(ProgramRef, chrono::DateTime<chrono::Local>),
|
||||
}
|
||||
|
||||
pub type ProgramEventRecv = broadcast::Receiver<ProgramEvent>;
|
||||
@ -136,7 +137,7 @@ impl ProgramRunnerInner {
|
||||
|
||||
fn update_schedules(&mut self, ctx: &mut actix::Context<ProgramRunnerActor>) {
|
||||
let mut scheduled_run_queue = DelayQueue::with_capacity(self.programs.len());
|
||||
for (_, prog) in &self.programs {
|
||||
for (_, prog) in self.programs.clone() {
|
||||
if !prog.enabled {
|
||||
continue;
|
||||
}
|
||||
@ -148,6 +149,7 @@ impl ProgramRunnerInner {
|
||||
let delay = (next_run - ref_time).to_std().unwrap();
|
||||
trace!("will run program in {:?}", delay);
|
||||
scheduled_run_queue.insert(prog.clone(), delay);
|
||||
self.send_event(ProgramEvent::NextRun(prog, next_run));
|
||||
}
|
||||
let fut = actix::fut::wrap_stream(scheduled_run_queue)
|
||||
.map(|item, act: &mut ProgramRunnerActor, ctx| act.handle_scheduled_run(item, ctx))
|
||||
|
@ -154,6 +154,17 @@ impl MqttInterface {
|
||||
.wrap_err("failed to publish program running")
|
||||
}
|
||||
|
||||
pub async fn publish_program_next_run(
|
||||
&mut self,
|
||||
program_id: ProgramId,
|
||||
next_run: chrono::DateTime<chrono::Local>,
|
||||
) -> eyre::Result<()> {
|
||||
let payload = next_run.to_rfc3339();
|
||||
self.publish_data(self.topics.program_next_run(program_id), &payload)
|
||||
.await
|
||||
.wrap_err("failed to publish program next run")
|
||||
}
|
||||
|
||||
pub async fn publish_section_runner(&mut self, sr_state: &SecRunnerState) -> eyre::Result<()> {
|
||||
let json: SecRunnerStateJson = sr_state.into();
|
||||
self.publish_data(self.topics.section_runner(), &json)
|
||||
|
@ -44,6 +44,11 @@ where
|
||||
format!("{}/programs/{}/running", self.prefix.as_ref(), program_id)
|
||||
}
|
||||
|
||||
pub fn program_next_run(&self, program_id: ProgramId) -> String {
|
||||
// TODO: reconcile naming convention
|
||||
format!("{}/programs/{}/nextRun", self.prefix.as_ref(), program_id)
|
||||
}
|
||||
|
||||
pub fn section_runner(&self) -> String {
|
||||
format!("{}/section_runner", self.prefix.as_ref())
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use sprinklers_actors::{
|
||||
use actix::{fut::wrap_future, Actor, ActorContext, Addr, AsyncContext, Handler, StreamHandler};
|
||||
use futures_util::TryFutureExt;
|
||||
use sprinklers_core::model::Programs;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{broadcast, watch};
|
||||
use tracing::{trace, warn};
|
||||
|
||||
@ -85,17 +84,37 @@ impl StreamHandler<Result<ProgramEvent, broadcast::RecvError>> for UpdateListene
|
||||
return;
|
||||
}
|
||||
};
|
||||
let (program_id, running) = match event {
|
||||
ProgramEvent::RunStart(prog) => (prog.id, true),
|
||||
ProgramEvent::RunFinish(prog) | ProgramEvent::RunCancel(prog) => (prog.id, false),
|
||||
};
|
||||
let mut mqtt_interface = self.mqtt_interface.clone();
|
||||
let fut = async move {
|
||||
if let Err(err) = mqtt_interface
|
||||
.publish_program_running(program_id, running)
|
||||
.await
|
||||
{
|
||||
warn!("could not publish program running: {}", err);
|
||||
enum Publish {
|
||||
Running(bool),
|
||||
NextRun(chrono::DateTime<chrono::Local>),
|
||||
}
|
||||
|
||||
let (program_id, publish) = match event {
|
||||
ProgramEvent::RunStart(prog) => (prog.id, Publish::Running(true)),
|
||||
ProgramEvent::RunFinish(prog) | ProgramEvent::RunCancel(prog) => {
|
||||
(prog.id, Publish::Running(false))
|
||||
}
|
||||
ProgramEvent::NextRun(prog, next_run) => (prog.id, Publish::NextRun(next_run)),
|
||||
};
|
||||
match publish {
|
||||
Publish::Running(running) => {
|
||||
if let Err(err) = mqtt_interface
|
||||
.publish_program_running(program_id, running)
|
||||
.await
|
||||
{
|
||||
warn!("could not publish program running: {}", err);
|
||||
}
|
||||
}
|
||||
Publish::NextRun(next_run) => {
|
||||
if let Err(err) = mqtt_interface
|
||||
.publish_program_next_run(program_id, next_run)
|
||||
.await
|
||||
{
|
||||
warn!("could not publish program next run: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ctx.spawn(wrap_future(fut));
|
||||
|
@ -39,8 +39,6 @@ async fn main() -> Result<()> {
|
||||
|
||||
let state_manager = crate::state_manager::StateManagerThread::start(db_conn);
|
||||
|
||||
program_runner.listen_programs(state_manager.get_programs());
|
||||
|
||||
let mqtt_options = mqtt::Options {
|
||||
broker_host: "localhost".into(),
|
||||
broker_port: 1883,
|
||||
@ -62,6 +60,9 @@ async fn main() -> Result<()> {
|
||||
update_listener.listen_programs(state_manager.get_programs());
|
||||
update_listener.listen_program_events(program_runner.subscribe().await?);
|
||||
|
||||
// Only listen to programs now so above subscriptions get events
|
||||
program_runner.listen_programs(state_manager.get_programs());
|
||||
|
||||
program_runner.update_sections(sections.clone()).await?;
|
||||
// TODO: update listener should probably do this
|
||||
mqtt_interface.publish_sections(§ions).await?;
|
||||
|
Loading…
x
Reference in New Issue
Block a user