fix(startup): recover from core port 7788 conflict automatically (#2626)

This commit is contained in:
Mega Mind
2026-05-25 20:09:08 +05:30
committed by GitHub
parent d997394116
commit cdee8f73fb
27 changed files with 1209 additions and 45 deletions
+56 -1
View File
@@ -397,7 +397,7 @@ impl CoreProcessHandle {
)
}
fn apply_embedded_ready_signal(
pub(crate) fn apply_embedded_ready_signal(
&self,
ready: openhuman_core::core::jsonrpc::EmbeddedReadySignal,
) {
@@ -630,6 +630,61 @@ impl CoreProcessHandle {
}
}
/// Result returned to the frontend after a port-conflict auto-recovery attempt.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RecoveryOutcome {
pub success: bool,
pub message: String,
pub new_port: Option<u16>,
}
impl CoreProcessHandle {
/// Attempt to recover from a port conflict: reap stale OpenHuman processes,
/// wait briefly for the port to free, then start the embedded core.
///
/// Called from the `recover_port_conflict` Tauri command when the frontend's
/// boot-check detects the core is unreachable due to a port conflict.
pub async fn recover_port_conflict(&self) -> RecoveryOutcome {
log::debug!(
"[core_process] recover_port_conflict: starting recovery for port {}",
self.preferred_port
);
tokio::task::spawn_blocking(crate::process_recovery::reap_stale_openhuman_processes)
.await
.unwrap_or_else(|e| {
log::warn!("[core_process] recover_port_conflict: reap task panicked: {e}")
});
log::debug!("[core_process] recover_port_conflict: stale process reap complete");
// Give the OS time to release the port after process termination.
tokio::time::sleep(Duration::from_millis(500)).await;
log::debug!("[core_process] recover_port_conflict: post-reap wait complete");
match self.ensure_running().await {
Ok(()) => {
let new_port = self.port();
log::info!(
"[core_process] recover_port_conflict: recovery succeeded, core on port {new_port}"
);
RecoveryOutcome {
success: true,
message: format!("Core recovered on port {new_port}"),
new_port: Some(new_port),
}
}
Err(err) => {
log::warn!("[core_process] recover_port_conflict: recovery failed: {err}");
RecoveryOutcome {
success: false,
message: format!("Recovery failed: {err}"),
new_port: None,
}
}
}
}
}
pub fn default_core_port() -> u16 {
std::env::var("OPENHUMAN_CORE_PORT")
.ok()