use anyhow::Result; use log::*; use tokio::{ select, sync::watch, time::{self, Duration}, }; use crate::config::RuntimeConfigAcme; use crate::messages; pub struct AcmeActor { email: String, last_ports: messages::PublicExposedPorts, refresh: Duration, rx_ports: watch::Receiver, } impl AcmeActor { pub async fn new( config: Option, rxp: &watch::Receiver, ) -> Result> { if config.is_none() { return Ok(None); } let config = config.unwrap(); let ctx = Self { email: config.email, last_ports: messages::PublicExposedPorts::new(), refresh: config.refresh_time, rx_ports: rxp.clone(), }; Ok(Some(ctx)) } pub async fn listen(&mut self) -> Result<()> { let mut interval = time::interval(self.refresh); loop { // 1. Wait for an event let new_ports = select! { Some(ports) = self.rx_ports.recv() => Some(ports), _ = interval.tick() => None, else => return Ok(()) // Sender dropped, terminate loop. }; // 2. Update last ports if needed if let Some(p) = new_ports { self.last_ports = p; } // 3. Flush IGD requests match self.do_acme().await { Ok(()) => debug!("Successfully updated ACME"), Err(e) => error!("An error occured while updating ACME. {}", e), } } } pub async fn do_acme(&self) -> Result<()> { debug!("Doing ACME!!!"); debug!("{:#?}", self.last_ports); Ok(()) } }