[Fix] IPC, cli, daemon

This commit is contained in:
Alex-Emmet 2026-07-21 23:05:34 +02:00
commit 56aad3a023
32 changed files with 1356 additions and 399 deletions

View file

@ -12,3 +12,4 @@ iota-storage = { path = "../iota-storage" }
omikron-connector = { path = "../omikron-connector" }
web-server = { path = "../web-server" }
tokio = { version = "1.50.0", features = ["full"] }
tokio-util = { version = "0.7", features = ["rt"] }

View file

@ -1,12 +1,11 @@
use iota_daemon_lib::{DaemonRuntime, IpcServer, log_broadcaster};
use iota_daemon_lib::{DaemonRuntime, IpcServer, ShutdownReason, StartupPhase, log_broadcaster};
use iota_logger::{self as logger, log, log_t};
use iota_storage::users::user_manager;
use iota_storage::util::config_util::CONFIG;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::broadcast;
use tokio::sync::{broadcast, watch};
fn socket_path() -> PathBuf {
std::env::var_os("IOTA_SOCKET")
.map(PathBuf::from)
@ -17,42 +16,79 @@ fn socket_path() -> PathBuf {
async fn main() {
logger::startup();
iota_storage::util::config_util::load_config();
let runtime = Arc::new(DaemonRuntime::new());
runtime.set_startup_phase(StartupPhase::LoadingUsers);
if user_manager::load_users().await.is_err() {
log_t!("user_load_failed");
}
let runtime = Arc::new(DaemonRuntime::new());
// --- IPC infrastructure ---
let (log_tx, _) = broadcast::channel(512);
log_broadcaster::spawn(log_tx.clone());
let (state_tx, _state_rx) = watch::channel(iota_ipc::StateSnapshot::default());
// --- Start IPC server early (before services) so clients can see startup phases ---
runtime.set_startup_phase(StartupPhase::StartingServices);
let ipc_server = IpcServer::new(
socket_path(),
runtime.clone(),
log_tx.clone(),
state_tx.clone(),
);
tokio::spawn(async move {
if let Err(error) = ipc_server.run().await {
eprintln!("iota-daemon IPC server failed: {error}");
}
});
log!("iota-daemon IPC server started");
// --- System monitor ---
runtime.spawn_system_monitor();
let (messages, _) = broadcast::channel(512);
log_broadcaster::spawn(messages.clone());
let state_updates = runtime.clone();
let state_messages = messages.clone();
// --- State update publisher (watch-based, no full broadcast per tick) ---
let state_publisher = runtime.clone();
tokio::spawn(async move {
loop {
if *state_updates.state.shutdown.read().await {
if state_publisher.is_shutting_down() {
break;
}
let _ = state_messages.send(iota_ipc::DaemonMessage::StateUpdate(
state_updates.snapshot(),
));
let snapshot = state_publisher.snapshot();
let _ = state_tx.send(snapshot);
tokio::time::sleep(Duration::from_millis(500)).await;
}
});
// --- Web server ---
let port = CONFIG.load().port;
if !web_server::start(port).await {
if !web_server::start(port, runtime.cancellation.clone()).await {
log!("Failed to start the MTP web server on port {}", port);
runtime.mark_degraded("MTP web server failed to start".into());
}
let _ = omikron_connector::omikron_connection::get_omikron_connection().await;
let server = IpcServer::new(socket_path(), runtime.clone(), messages);
tokio::spawn(async move {
if let Err(error) = server.run().await {
eprintln!("iota-daemon IPC server failed: {error}");
}
});
log!("iota-daemon started");
while !*runtime.state.shutdown.read().await {
tokio::time::sleep(Duration::from_millis(250)).await;
// --- Omikron connection ---
let omikron_result =
omikron_connector::omikron_connection::get_omikron_connection(runtime.cancellation.clone())
.await;
if omikron_result.is_none() {
runtime.mark_degraded("Omikron connection unavailable".into());
}
log!("iota-daemon stopping");
runtime.set_startup_phase(StartupPhase::Ready);
log!("iota-daemon started (phase: Ready)");
// --- Main lifecycle loop ---
runtime.cancellation.cancelled().await;
let reason = runtime.shutdown_reason().unwrap_or(ShutdownReason::Stop);
log!("iota-daemon shutting down (reason: {:?})", reason);
runtime.set_startup_phase(StartupPhase::Stopping);
// Wait a moment for in-flight operations to complete
tokio::time::sleep(Duration::from_millis(500)).await;
let exit_code = reason.exit_code();
log!("iota-daemon exited (code: {})", exit_code);
std::process::exit(exit_code);
}