|
8 | 8 | use chrono::{DateTime, TimeDelta, Timelike as _, Utc}; |
9 | 9 | use frequenz_microgrid_formula_engine::FormulaEngine; |
10 | 10 | use frequenz_resampling::ResamplingFunction; |
11 | | -use std::collections::HashMap; |
| 11 | +use std::collections::{HashMap, HashSet}; |
12 | 12 | use tokio::sync::{broadcast, mpsc, oneshot}; |
13 | 13 | use tokio::time::{MissedTickBehavior, interval}; |
14 | 14 |
|
@@ -218,14 +218,37 @@ impl LogicalMeterActor { |
218 | 218 | comp_data.insert(resampler.component_id, resampled[0].clone().value()); |
219 | 219 | } |
220 | 220 |
|
221 | | - for (_, formula) in formulas.iter_mut() { |
| 221 | + let mut formulas_to_drop = vec![]; |
| 222 | + for (formula_str, formula) in formulas.iter_mut() { |
222 | 223 | let result = formula.formula.calculate(&comp_data).map_err(|e| { |
223 | 224 | Error::formula_engine_error(format!("Failed to evaluate formula: {e}")) |
224 | 225 | })?; |
225 | | - formula |
226 | | - .sender |
227 | | - .send(Sample::new(self.next_ts, result)) |
228 | | - .map_err(|_| Error::internal("Failed to send sample for formula".to_string()))?; |
| 226 | + |
| 227 | + if let Err(e) = formula.sender.send(Sample::new(self.next_ts, result)) { |
| 228 | + tracing::debug!("No remaining subscribers for formula: {formula_str}. Err: {e}"); |
| 229 | + formulas_to_drop.push(formula_str.to_string()); |
| 230 | + } |
| 231 | + } |
| 232 | + |
| 233 | + for formula_str in &formulas_to_drop { |
| 234 | + if let Some(formula) = formulas.remove(formula_str) { |
| 235 | + tracing::debug!("Dropping formula: {}", formula_str); |
| 236 | + drop(formula); |
| 237 | + } |
| 238 | + } |
| 239 | + if !formulas_to_drop.is_empty() { |
| 240 | + let mut components = HashSet::<u64>::new(); |
| 241 | + for (_, formula) in formulas.iter() { |
| 242 | + components.extend(formula.formula.components()); |
| 243 | + } |
| 244 | + resamplers.retain(|component_id, _| { |
| 245 | + if components.contains(component_id) { |
| 246 | + true |
| 247 | + } else { |
| 248 | + tracing::debug!("Dropping resampler for component {}", component_id); |
| 249 | + false |
| 250 | + } |
| 251 | + }); |
229 | 252 | } |
230 | 253 |
|
231 | 254 | self.next_ts += self.config.resampling_interval; |
|
0 commit comments