use std::collections::{BTreeMap, BTreeSet}; use std::time::SystemTime; use redis::Commands; use tracing::{info, warn}; use rayon::prelude::*; use crate::client_manager::ClientManager; use crate::models::{TrackerInfo, TrackerMap}; pub fn get_trackers(client_mgr: &ClientManager) -> color_eyre::Result { let mut con = client_mgr.get_master_connection()?; let trackers: BTreeMap = con.hgetall("trackers")?; let mut errors = vec![]; let trackers: BTreeMap = trackers.into_iter() .map(|(name, info)| { let info: serde_json::Result = serde_json::from_str(&info); (name, info) }) .filter_map(|(n,v)| { v.map_err(|e| errors.push((n.clone(), e))) .ok() .map(|v| (n, v)) }) .collect(); for (n, e) in errors { warn!("Unable to parse tracker data for {n}: {e}"); } Ok(trackers) } pub fn determine_active_trackers(client_mgr: &ClientManager, trackers: &TrackerMap, inactive_minutes: u64) -> color_eyre::Result> { let start = SystemTime::now(); let t = get_last_requests_time()?; let res: color_eyre::Result>> = trackers.par_iter().map(|(name, info)| { let mut con = client_mgr.get_connection_from_tracker(info)?; for i in 0..inactive_minutes { let tim = t.clone() - i * 60u64; let k = format!("{name}:requests_processed:{tim}"); let ex: bool = con.exists(k)?; if ex { return Ok(Some(name.clone())) } } Ok(None) }) .collect(); let res = res?; let dur = SystemTime::now().duration_since(start).unwrap().as_secs_f32(); info!("Determining active projects took {dur:.04} seconds."); Ok(res.into_iter().filter_map(|v| v).collect()) } pub fn get_last_requests_time() -> color_eyre::Result { let now = SystemTime::now(); let unix = now.duration_since(SystemTime::UNIX_EPOCH)?.as_secs(); let unix = unix - 60; let d = unix.clone() % 60; Ok(unix - d) }