hpc_node/readiness.rs
1//! Boot readiness signaling.
2//!
3//! Defines the protocol for signaling that a node is fully initialized
4//! and ready for workload allocations.
5
6/// Well-known readiness socket path.
7pub const READINESS_SOCKET_PATH: &str = "/run/pact/ready.sock";
8
9/// Well-known readiness file path (alternative to socket).
10///
11/// pact-agent creates this file when all boot phases complete.
12/// lattice-node-agent can poll for its existence.
13pub const READINESS_FILE_PATH: &str = "/run/pact/ready";
14
15/// Trait for readiness signaling.
16///
17/// pact-agent implements this as a provider (emits readiness).
18/// lattice-node-agent implements this as a consumer (waits for readiness).
19pub trait ReadinessGate: Send + Sync {
20 /// Check if the node is ready for allocations.
21 ///
22 /// Returns `true` once all boot phases have completed and the
23 /// readiness signal has been emitted.
24 fn is_ready(&self) -> bool;
25
26 /// Wait until the node is ready.
27 ///
28 /// Returns immediately if already ready. Blocks until readiness
29 /// is signaled or an error occurs (e.g., boot failure).
30 ///
31 /// Lattice requests received before readiness should be queued,
32 /// not rejected.
33 fn wait_ready(&self) -> Result<(), ReadinessError>;
34}
35
36/// Errors from readiness operations.
37#[derive(Debug, thiserror::Error)]
38pub enum ReadinessError {
39 #[error("boot failed: {reason}")]
40 BootFailed { reason: String },
41
42 #[error("timeout waiting for readiness")]
43 Timeout,
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn well_known_paths() {
52 assert!(READINESS_SOCKET_PATH.starts_with("/run/pact/"));
53 assert!(READINESS_FILE_PATH.starts_with("/run/pact/"));
54 }
55}