use std::{sync::Arc, time::Duration};
use either::Either;
use wgroup::{WaitGroup, WaitGroupHandle, WaitGuard};
use crate::{executor_pool::ExecutorPool, grpc::GrpcImpl};
mod broadcast;
mod executor_pool;
mod grpc;
pub mod proto;
mod server;
mod util;
pub use grpc::GrpcServices;
pub use ora_backend::Backend;
#[derive(Debug, Clone)]
pub struct ServerOptions {
pub delete_history_after: Duration,
pub shutdown_grace_period: Duration,
}
impl Default for ServerOptions {
fn default() -> Self {
Self {
delete_history_after: Default::default(),
shutdown_grace_period: Duration::from_secs(15),
}
}
}
#[must_use]
pub struct ServerBuilder<B> {
backend: Arc<B>,
options: ServerOptions,
}
impl<B> ServerBuilder<B> {
pub fn new(backend: B, options: ServerOptions) -> Self {
Self {
backend: Arc::new(backend),
options,
}
}
pub fn delete_history_after(mut self, duration: Duration) -> Self {
self.options.delete_history_after = duration;
self
}
pub fn shutdown_grace_period(mut self, duration: Duration) -> Self {
self.options.shutdown_grace_period = duration;
self
}
}
impl<B> ServerBuilder<B>
where
B: Backend,
{
pub fn spawn(self) -> ServerHandle<B> {
server::spawn_server(self.backend, self.options, Either::Left(WaitGroup::new()))
}
pub fn spawn_with_wg(self, wg: WaitGroupHandle) -> ServerHandle<B> {
server::spawn_server(self.backend, self.options, Either::Right(wg))
}
}
#[derive(Debug)]
#[must_use]
pub struct ServerHandle<B> {
backend: Arc<B>,
executor_pool: ExecutorPool,
wg: Either<WaitGroup, WaitGroupHandle>,
}
impl<B> ServerHandle<B> {
#[allow(clippy::missing_panics_doc)]
pub async fn stop(self) {
if let Either::Left(wg) = self.wg {
wg.all_done().await;
}
}
#[doc(hidden)]
pub fn add_wg_internal(&self) -> WaitGuard {
match &self.wg {
Either::Left(wg) => wg.add(),
Either::Right(handle) => handle.add(),
}
}
}
impl<B> ServerHandle<B>
where
B: Backend,
{
#[must_use]
pub fn grpc(&self) -> impl GrpcServices + Send + Sync + 'static {
GrpcImpl {
backend: self.backend.clone(),
executor_pool: self.executor_pool.clone(),
wg: match &self.wg {
Either::Left(wg) => wg.handle(),
Either::Right(handle) => handle.clone(),
},
}
}
}