use std::sync::Arc;
mod boot_guard;
mod connection;
mod dispatch_trait;
mod locks;
mod process_files;
mod run_daemon;
pub use dispatch_trait::*;
#[cfg(all(unix, feature = "fault-injection"))]
pub use connection::handle_conn_for_test;
use connection::*;
#[cfg(unix)]
pub use run_daemon::*;
#[cfg(unix)]
pub use boot_guard::*;
#[cfg(all(test, unix))]
use locks::open_lock_file;
#[cfg(unix)]
pub use locks::{
acquire_daemon_boot_guard, acquire_recovery_lock, try_acquire_daemon_boot_guard_until,
try_acquire_recoverer_lock_until, DaemonBootGuard,
};
#[cfg(unix)]
pub(crate) use locks::{peer_uid, uid_is_permitted};
#[cfg(unix)]
use locks::{socket_identity, SocketIdentity};
pub use process_files::*;
mod store_guard;
mod store_identity;
#[cfg(unix)]
use store_guard::ensure_claimed_parent_identity;
#[cfg(unix)]
pub use store_guard::{acquire_daemon_store_guards, bind_daemon_store_files, claim_stores};
pub use store_guard::{assert_daemon_store_identities, DaemonStoreGuard};
#[cfg(unix)]
pub use store_identity::claimed_daemon_store_identity;
mod supervisor_marker;
#[cfg(unix)]
pub use supervisor_marker::supervisor_marker_path;
#[cfg(unix)]
use std::io::Write as _;
#[cfg(unix)]
use std::os::unix::fs::{MetadataExt, PermissionsExt};
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
#[cfg(all(test, unix))]
use std::path::PathBuf;
#[cfg(unix)]
use async_trait::async_trait;
#[cfg(unix)]
use libc;
#[cfg(unix)]
use serde::Deserialize;
#[cfg(unix)]
use tokio::io::AsyncReadExt;
#[cfg(all(test, unix))]
use tokio::io::AsyncWriteExt;
#[cfg(unix)]
use tokio::net::{UnixListener, UnixStream};
#[cfg(unix)]
use crate::pack::RequestIdentity;
#[cfg(unix)]
use khive_db::{run_checkpoint_task, CheckpointConfig, CheckpointLifecycleOwner, ConnectionPool};
mod exit_record;
mod lifecycle;
#[cfg(unix)]
use lifecycle::khive_dir;
#[cfg(test)]
use lifecycle::khive_root_from;
#[cfg(unix)]
use lifecycle::{
current_supervisor_claim, default_socket_path, ensure_rendezvous_overrides_paired,
read_supervisor_marker_claim, DaemonLifecycle, PID_PATH_ENV, SOCKET_PATH_ENV,
};
pub use lifecycle::{
lock_path, volume_lock_dir, DaemonLifecyclePhase, DaemonLifecycleSnapshot, DaemonLifetime,
DaemonOptions, DaemonShutdownReason, DaemonStartupReport, DEFAULT_DEMAND_IDLE_SECS,
};
#[cfg(unix)]
pub use lifecycle::{
pid_path, recoverer_lock_path, rendezvous_split, socket_path, RendezvousSplit,
SUPERVISOR_CLAIM_ENV,
};
mod load_limits;
#[cfg(unix)]
use load_limits::{admit_or_refuse_busy, ConnectionAdmission};
pub use load_limits::{
recall_ledger_snapshot, track_recall_ledger_task, ConnectionCapSnapshot, RecallLedgerSnapshot,
};
pub const MAX_FRAME_BYTES: usize = 8 * 1024 * 1024;
pub const PROTOCOL_VERSION: u32 = 8;
#[doc(hidden)]
pub const DAEMON_LEXICAL_TIMEOUT_MARKER: &str = "__khive_daemon_lexical_timeout";
const DEFAULT_DRAIN_TIMEOUT_SECS: u64 = 10;
#[cfg(unix)]
const INITIAL_FRAME_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
#[cfg(unix)]
fn next_accept_error_backoff(previous: Option<std::time::Duration>) -> std::time::Duration {
previous
.map(|delay| delay.saturating_mul(2))
.unwrap_or_else(|| std::time::Duration::from_millis(10))
.min(std::time::Duration::from_secs(1))
}
mod config_id;
#[cfg(test)]
use config_id::parse_config_id;
pub use config_id::{
config_id_extra_embedder_exclusions, config_ids_compatible, first_config_mismatch_field,
};
mod wire_frames;
#[cfg(unix)]
pub use wire_frames::{read_frame, write_frame};
#[cfg(unix)]
use wire_frames::{read_initial_frame, take_daemon_lexical_timeout_marker};
pub use wire_frames::{
CheckpointStoreMetrics, DaemonDispatchError, DaemonRequestFrame, DaemonResponseFrame,
MetricsSnapshot, ERROR_DETAIL_NESTING_DEPTH_LIMIT,
};
#[cfg(unix)]
pub fn env_truthy(key: &str) -> bool {
std::env::var(key)
.map(|v| {
let v = v.trim();
!v.is_empty() && v != "0" && !v.eq_ignore_ascii_case("false")
})
.unwrap_or(false)
}
include!("daemon_khive_root_tests.rs");
#[cfg(all(unix, any(test, feature = "test-internals")))]
#[doc(hidden)]
pub async fn serve_connection_for_test<D: DaemonDispatch>(stream: UnixStream, dispatcher: D) {
handle_conn_with_shutdown(
stream,
dispatcher,
None,
tokio::time::Instant::now() + INITIAL_FRAME_READ_TIMEOUT,
)
.await;
}
#[cfg(all(test, unix))]
#[path = "daemon_tests.rs"]
mod tests;