photoncloud-monorepo/deployer/crates/deployer-server/src/state.rs
centra 3eeb303dcb feat: Batch commit for T039.S3 deployment
Includes all pending changes needed for nixos-anywhere:
- fiberlb: L7 policy, rule, certificate types
- deployer: New service for cluster management
- nix-nos: Generic network modules
- Various service updates and fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 04:34:51 +09:00

83 lines
2.4 KiB
Rust

use deployer_types::NodeInfo;
use std::collections::HashMap;
use tokio::sync::{Mutex, RwLock};
use tracing::{info, warn};
use crate::config::Config;
use crate::storage::NodeStorage;
/// Application state shared across handlers
pub struct AppState {
/// Server configuration
pub config: Config,
/// ChainFire-backed storage (when available)
pub storage: Option<Mutex<NodeStorage>>,
/// Fallback in-memory node registry
/// Key: node_id, Value: NodeInfo
pub nodes: RwLock<HashMap<String, NodeInfo>>,
/// Fallback in-memory machine_id → (node_id, NodeConfig) mapping
pub machine_configs:
RwLock<HashMap<String, (String, deployer_types::NodeConfig)>>,
}
impl AppState {
/// Create new application state with default config
pub fn new() -> Self {
Self::with_config(Config::default())
}
/// Create application state with custom config
pub fn with_config(config: Config) -> Self {
Self {
config,
storage: None,
nodes: RwLock::new(HashMap::new()),
machine_configs: RwLock::new(HashMap::new()),
}
}
/// Initialize ChainFire storage connection
pub async fn init_storage(&mut self) -> anyhow::Result<()> {
if self.config.chainfire.endpoints.is_empty() {
warn!("No ChainFire endpoints configured, using in-memory storage");
return Ok(());
}
let endpoint = &self.config.chainfire.endpoints[0];
let namespace = &self.config.chainfire.namespace;
match NodeStorage::connect(endpoint, namespace).await {
Ok(storage) => {
info!(
endpoint = %endpoint,
namespace = %namespace,
"Connected to ChainFire storage"
);
self.storage = Some(Mutex::new(storage));
Ok(())
}
Err(e) => {
warn!(
error = %e,
"Failed to connect to ChainFire, using in-memory storage"
);
// Continue with in-memory storage as fallback
Ok(())
}
}
}
/// Check if ChainFire storage is available
pub fn has_storage(&self) -> bool {
self.storage.is_some()
}
}
impl Default for AppState {
fn default() -> Self {
Self::new()
}
}