From 4d07e0339569461ac1a4c90c02dfcba7e5fad089 Mon Sep 17 00:00:00 2001 From: Mollusk Date: Fri, 19 Jun 2026 15:57:35 -0400 Subject: [PATCH] core: skip network-stack rebuild when SetNetworkMode is a no-op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GUI re-sends the saved network mode as part of its startup config-sync. The SetNetworkMode handler unconditionally tore down + rebuilt the iroh endpoint whenever idle, so every launch rebuilt the freshly-built stack for an identical posture — a needless ~1s teardown+rebuild bounce visible in the logs on both Linux and Windows/Wine (the 'start core loop -> shut down network stack ~1s later' pattern from the Wine spike). Guard the rebuild on an actual mode change; a real change still rebuilds exactly as before. Co-Authored-By: Claude Opus 4.8 --- src/core/mod.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/core/mod.rs b/src/core/mod.rs index e3bc8d9..afd8341 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1816,17 +1816,26 @@ async fn run_core_loop( } CoreCommand::SetNetworkMode(mode) => { - network_mode = mode; - // Rebuild the persistent stack to the new posture immediately if - // idle; if a call is active, defer to the next Leave/Join so the - // live call isn't disrupted (preserves "applies on next join"). - if active_session.is_none() { - let lookup = net.memory_lookup.clone(); - net.shutdown().await; - let publish = presence_mode.lock().unwrap().publishes_to_discovery(); - net = build_net_stack(secret_key.clone(), network_mode, lookup, friends_handler.clone(), publish).await?; - } else { - net_rebuild_pending = true; + // Skip when the posture is unchanged. The GUI re-sends the saved + // network mode as part of its startup config-sync, and that mode + // usually already matches the freshly-built stack — rebuilding the + // iroh endpoint for an identical posture just churns the network + // and adds a needless ~1s teardown+rebuild bounce at every launch + // (seen on both Linux and Windows/Wine). A real change still + // rebuilds exactly as before. + if mode != network_mode { + network_mode = mode; + // Rebuild the persistent stack to the new posture immediately if + // idle; if a call is active, defer to the next Leave/Join so the + // live call isn't disrupted (preserves "applies on next join"). + if active_session.is_none() { + let lookup = net.memory_lookup.clone(); + net.shutdown().await; + let publish = presence_mode.lock().unwrap().publishes_to_discovery(); + net = build_net_stack(secret_key.clone(), network_mode, lookup, friends_handler.clone(), publish).await?; + } else { + net_rebuild_pending = true; + } } }