use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use tracing::{info, warn};
use super::guard::{RecordUpdate, update_record};
use super::pid_file::{PidRecord, now_unix_secs};
pub const STAGE_CONFIG: &str = "config";
pub const STAGE_STORE_OPEN: &str = "store-open";
pub const STAGE_WRITER_LOCK_WAIT: &str = "writer-lock-wait";
pub const STAGE_WAL_RECOVERY: &str = "wal-recovery";
pub const STAGE_ENGINE_RECOVERY: &str = "engine-recovery";
pub const STAGE_BINDING: &str = "binding";
#[derive(Clone, Debug)]
pub struct StageReporter {
path: PathBuf,
record: Arc<Mutex<PidRecord>>,
holds_claim: bool,
}
impl StageReporter {
pub(super) fn new(path: PathBuf, record: Arc<Mutex<PidRecord>>, holds_claim: bool) -> Self {
Self {
path,
record,
holds_claim,
}
}
#[must_use]
pub fn detached() -> Self {
Self {
path: PathBuf::new(),
record: Arc::new(Mutex::new(detached_record())),
holds_claim: false,
}
}
pub fn report(&self, stage: &str, detail: String) {
info!(
boot_stage = stage,
boot_stage_detail = %detail,
"boot stage"
);
let stage_owned = stage.to_owned();
let update = update_record(&self.path, &self.record, self.holds_claim, move |record| {
record.stage = Some(stage_owned);
record.stage_detail = Some(detail);
record.stage_seq = record.stage_seq.saturating_add(1);
record.stage_updated_at_unix_secs = now_unix_secs();
});
match update {
Ok(RecordUpdate::Written | RecordUpdate::Unclaimed | RecordUpdate::NotOurs) => {}
Err(error) => warn!(
%error,
boot_stage = stage,
"could not write the boot stage into this home's pid record; the \
stage is in the log above, but `aion server status` and the \
launcher will not see it"
),
}
}
}
fn detached_record() -> PidRecord {
PidRecord {
pid: 0,
started_at_unix_secs: 0,
binary_sha256: String::new(),
version: String::new(),
commit: String::new(),
state: super::pid_file::IncarnationState::Booting,
http_address: None,
grpc_address: None,
intended_http_address: None,
intended_grpc_address: None,
stage: None,
stage_detail: None,
stage_seq: 0,
stage_updated_at_unix_secs: 0,
drain_timeout_seconds: 0,
}
}
#[cfg(test)]
#[path = "stage_tests.rs"]
mod tests;