use eyre::Result; use async_trait::async_trait; use tokio::task::spawn_local; use std::time::Instant; use std::sync::Arc; use tokio::sync::oneshot; use tokio::sync::mpsc; use crate::event::Event; use crate::endpoint::Endpoint; use crate::irc_endpoint::IrcEndpoint; pub struct RircdState { endpoints: Vec>, //to determine program runtime creation_timestamp: Option, plainlog: Option<()>, sqlite_log: Option<()>, postgres_log: Option<()>, } impl RircdState { pub fn new() -> Result { //TODO remove (for testing) let eps: Vec> = vec![ Arc::new(IrcEndpoint {} ), ]; //TODO impl Ok(RircdState { endpoints: eps, //endpoints: vec![], creation_timestamp: Some(Instant::now()), plainlog: None, sqlite_log: None, postgres_log: None, }) } //TODO impl pub fn from_config(config: String) -> Result { Self::new() } pub async fn run(mut self) -> Result<()> { //TODO choose good default/custom chan size let (event_sender,mut event_receiver) = mpsc::channel::(64); //try to start each endpoint self.endpoints.iter().filter(|ep| ep.is_active()).for_each(|endpoint| { let endpoint_name = endpoint.name(); let (success_status_send,success_status_recv) = oneshot::channel::>(); tokio::spawn(endpoint.clone().listen(success_status_send, event_sender.to_owned())); //TODO color err msg //TODO paralelize and sync at the end futures::executor::block_on(async move { println!("starting {} | {}", endpoint_name, match success_status_recv.await { Ok(_) => format!("SUCCEEDED |"), Err(e) => format!("FAILED | <{}>", e), }); }); }); //TODO Err() if not at least one Endpoint is running because //if none is running there is no way to activate further (user locked out) //> who needs a daemon that does nothing and where nothing can be configured to be done tokio::select! { event = event_receiver.recv() => { () }, } Ok(()) } }