use std::sync::Arc;
use kindling_client::Spawner;
#[cfg(feature = "embedded-daemon")]
use kindling_server::{serve, ServerConfig};
#[cfg(feature = "embedded-daemon")]
use std::sync::Mutex;
#[cfg(feature = "embedded-daemon")]
use tokio::task::JoinHandle;
#[cfg(feature = "embedded-daemon")]
pub(crate) type ServerHandleSlot =
Arc<Mutex<Option<JoinHandle<Result<(), kindling_server::ServerError>>>>>;
#[derive(Clone, Debug, Default)]
pub(crate) struct SpawnFlag(Arc<std::sync::atomic::AtomicBool>);
impl SpawnFlag {
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn mark(&self) {
self.0.store(true, std::sync::atomic::Ordering::SeqCst);
}
pub(crate) fn fired(&self) -> bool {
self.0.load(std::sync::atomic::Ordering::SeqCst)
}
}
#[cfg(feature = "embedded-daemon")]
pub(crate) fn embedded_spawner(
config: ServerConfig,
slot: ServerHandleSlot,
flag: SpawnFlag,
) -> Spawner {
Spawner::custom(move || {
flag.mark();
let cfg = config.clone();
let handle = tokio::spawn(async move { serve(cfg).await });
if let Ok(mut guard) = slot.lock() {
*guard = Some(handle);
}
Ok(())
})
}
pub(crate) fn attach_only_spawner(flag: SpawnFlag) -> Spawner {
Spawner::custom(move || {
flag.mark();
Err(std::io::Error::new(
std::io::ErrorKind::NotConnected,
"kindling-runtime: AttachOnly strategy will not start a daemon \
(no daemon is listening on the configured socket)",
))
})
}