//! One swarm-queue connection, shared by every consumer in this process. //! //! [`swarm_status`](crate::swarm_status) and //! [`swarm_notices`](crate::swarm_notices) both need the swarm queue, and //! both authenticate as the *same* identity (`hive-`, minted for //! this hive — see `swarm-authelia.nix`). Two independent `connect()` //! calls would be two token mints and two live connections for one //! identity, not two different credentials — the same shape that turned //! `swarm-controller`'s own connect into the shared `swarm-queue-client` //! crate in the first place, one layer up. This module is that same move //! made again, this time between two consumers *inside* one process. //! //! Connects lazily on first use rather than at boot — nothing here //! blocks `hive-c0re` starting up on hosts with no queue configured, //! which is the ordinary case. use tokio::sync::OnceCell; /// Env var prefix for this daemon's swarm-queue credentials — see /// [`swarm_queue_client::QueueConfig::from_env`]. All four or none. const ENV_PREFIX: &str = "HIVE_C0RE"; static CLIENT: OnceCell> = OnceCell::const_new(); /// The shared swarm-queue client, connecting on first call and memoized /// for the rest of the process's life. /// /// `None` covers both "no queue configured" (the ordinary case, logged /// once at `info`) and "config present but connecting failed" (bannered /// once via [`crate::warnings::set_boot_warning`] the first time this is /// called) — either way, a caller with `None` should just skip whatever /// it was about to publish. No caller needs to distinguish the two: both /// mean "this hive is not offering anything to the swarm right now." pub async fn client() -> Option { CLIENT.get_or_init(connect_once).await.clone() } async fn connect_once() -> Option { let cfg = match swarm_queue_client::QueueConfig::from_env(ENV_PREFIX) { Ok(Some(cfg)) => cfg, Ok(None) => { tracing::info!("no swarm queue configured; this hive offers nothing upward"); return None; } Err(e) => { // A one-shot startup step with no later retry to clear it — // exactly what `set_boot_warning` is for. `chain`, not // `{:#}`: this is `swarm_queue_client::Error`, whose // `Display` ignores the alternate flag (see `chain`'s own // doc comment), so `{:#}` would drop which env vars are // actually missing. crate::warnings::set_boot_warning( "swarm_queue_config", "warn", format!("swarm queue is off: {}", swarm_queue_client::chain(&e)), ); return None; } }; match swarm_queue_client::connect(cfg).await { Ok(client) => Some(client), Err(e) => { crate::warnings::set_boot_warning( "swarm_queue_config", "warn", format!("swarm queue is off: {}", swarm_queue_client::chain(&e)), ); None } } }