Rircd/src/state.rs

99 lines
3.2 KiB
Rust
Raw Normal View History

2021-09-16 20:55:05 +02:00
use eyre::Result;
2021-09-16 21:33:48 +02:00
use async_trait::async_trait;
2021-09-16 22:08:35 +02:00
use tokio::task::spawn_local;
2021-09-16 20:55:05 +02:00
use std::time::Instant;
use std::sync::Arc;
2021-09-16 21:33:48 +02:00
use tokio::sync::oneshot;
2021-09-16 22:40:40 +02:00
use tokio::sync::mpsc;
2021-09-16 23:59:37 +02:00
use crate::event::{EventKind,Event,EventResponse,InternalEvent};
2021-09-16 20:55:05 +02:00
use crate::endpoint::Endpoint;
2021-09-16 22:40:40 +02:00
use crate::irc_endpoint::IrcEndpoint;
2021-09-16 20:55:05 +02:00
pub struct RircdState {
endpoints: Vec<Arc<dyn Endpoint>>,
//to determine program runtime
creation_timestamp: Option<Instant>,
plainlog: Option<()>,
sqlite_log: Option<()>,
postgres_log: Option<()>,
}
impl RircdState {
pub fn new() -> Result<Self> {
2021-09-16 22:53:37 +02:00
//TODO remove (for testing)
2021-09-16 22:40:40 +02:00
let eps: Vec<Arc<dyn Endpoint>> = vec![
Arc::new(IrcEndpoint {} ),
];
2021-09-16 20:55:05 +02:00
//TODO impl
Ok(RircdState {
2021-09-16 22:40:40 +02:00
endpoints: eps,
//endpoints: vec![],
2021-09-16 20:55:05 +02:00
creation_timestamp: Some(Instant::now()),
plainlog: None,
sqlite_log: None,
postgres_log: None,
})
}
2021-09-16 21:33:48 +02:00
//TODO impl
pub fn from_config(config: String) -> Result<Self> {
Self::new()
}
pub async fn run(mut self) -> Result<()> {
2021-09-16 22:40:40 +02:00
//TODO choose good default/custom chan size
let (event_sender,mut event_receiver) = mpsc::channel::<Event>(64);
2021-09-16 21:38:52 +02:00
//try to start each endpoint
self.endpoints.iter().filter(|ep| ep.is_active()).for_each(|endpoint| {
2021-09-16 21:33:48 +02:00
let endpoint_name = endpoint.name();
2021-09-16 23:47:52 +02:00
let (success_status_send,success_status_recv) = oneshot::channel::<Result<mpsc::Sender<Event>>>();
2021-09-16 22:40:40 +02:00
tokio::spawn(endpoint.clone().listen(success_status_send, event_sender.to_owned()));
2021-09-16 21:33:48 +02:00
//TODO color err msg
2021-09-16 22:07:56 +02:00
//TODO paralelize and sync at the end
2021-09-16 22:40:40 +02:00
futures::executor::block_on(async move {
2021-09-16 22:07:56 +02:00
println!("starting {} | {}", endpoint_name,
match success_status_recv.await {
Ok(_) => format!("SUCCEEDED |"),
2021-09-16 22:40:40 +02:00
Err(e) => format!("FAILED | <{}>", e),
2021-09-16 22:07:56 +02:00
});
});
2021-09-16 21:38:52 +02:00
});
2021-09-16 22:07:56 +02:00
2021-09-16 22:40:40 +02:00
//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
2021-09-16 23:05:36 +02:00
loop {
println!("received event");
tokio::select! {
event = event_receiver.recv() => {
//TODO don't unwrap() I guess
2021-09-16 23:47:52 +02:00
let event = event.unwrap();
match event.kind {
EventKind::Internal(ev) => {
2021-09-16 23:59:37 +02:00
//TODO impl TODO don't unwrap
match ev {
InternalEvent::Shutdown => {
//TODO shutdown all endpoints
break;
},
_ => {},
}
assert!( event.result_sender.send(EventResponse::Success).is_ok());
2021-09-16 23:47:52 +02:00
},
2021-09-16 23:05:36 +02:00
EventKind::Message => {},
_ => {},
};
},
};
2021-09-16 22:40:40 +02:00
}
2021-09-16 22:07:56 +02:00
2021-09-16 21:33:48 +02:00
Ok(())
}
2021-09-16 20:55:05 +02:00
}