mod persistence; mod datastore; use crate::grpc::challenge::NodeUpdate; use tokio::sync::broadcast::Sender; use tokio::task::JoinSet; mod grpc; mod http_server; use crate::datastore::Store; use std::fs::File; use std::io::{BufRead, BufReader}; use std::sync::Arc; use tokio::sync::broadcast; use tokio::time::{sleep, Duration}; const INIT_NODES: &str = "detee_challenge_nodes"; const DISK_PERSISTENCE: &str = "detee_challenge_node_history"; async fn cycle_keys(ds: Arc, tx: Sender) { loop { sleep(Duration::from_secs(60)).await; let _ = tx.send(ds.reset_localhost_keys().await); } } #[tokio::main] async fn main() { let ds: Arc = Arc::new(Store::init(DISK_PERSISTENCE).await); ds.reset_localhost_keys().await; let (tx, mut _rx) = broadcast::channel(500); let mut long_term_tasks = JoinSet::new(); let mut init_tasks = JoinSet::new(); long_term_tasks.spawn(cycle_keys(ds.clone(), tx.clone())); long_term_tasks.spawn(http_server::init(ds.clone())); long_term_tasks.spawn(grpc::server::MyServer::init(ds.clone(), tx.clone()).start()); let input = File::open(INIT_NODES).unwrap(); let buffered = BufReader::new(input); for line in buffered.lines() { init_tasks.spawn( grpc::client::ConnManager::init(ds.clone(), tx.clone()).start_with_node(line.unwrap()), ); } let mut connection_count = 0; while init_tasks.join_next().await.is_some() { if connection_count < 3 { long_term_tasks.spawn(grpc::client::ConnManager::init(ds.clone(), tx.clone()).start()); connection_count += 1; } } while connection_count < 3 { long_term_tasks.spawn(grpc::client::ConnManager::init(ds.clone(), tx.clone()).start()); connection_count += 1; } // exit no matter which task finished long_term_tasks.join_next().await; println!("Shutting down..."); }