From cd13f4cd3a84fa0c75cf0e470f741514b15e59c5 Mon Sep 17 00:00:00 2001 From: Marco Allegretti Date: Fri, 13 Mar 2026 14:07:06 +0100 Subject: [PATCH] fix(appd): combine set_state and broadcast into one lock acquisition on READY The two consecutive registry lock acquisitions after READY left a window where session state was Running but the AppReady broadcast had not yet been sent. A concurrent reader winning the lock in that window would observe Running without a corresponding event. Combining into one acquisition closes the window. --- crates/weft-appd/src/runtime.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/weft-appd/src/runtime.rs b/crates/weft-appd/src/runtime.rs index 8f9aa8d..77e4686 100644 --- a/crates/weft-appd/src/runtime.rs +++ b/crates/weft-appd/src/runtime.rs @@ -315,14 +315,14 @@ pub(crate) async fn supervise( let app_shell = match ready_result { Some(Ok(Ok(remaining_stdout))) => { - registry - .lock() - .await - .set_state(session_id, AppStateKind::Running); - let _ = registry.lock().await.broadcast().send(Response::AppReady { - session_id, - app_id: app_id.to_owned(), - }); + { + let mut reg = registry.lock().await; + reg.set_state(session_id, AppStateKind::Running); + let _ = reg.broadcast().send(Response::AppReady { + session_id, + app_id: app_id.to_owned(), + }); + } tracing::info!(session_id, %app_id, "app ready"); tokio::spawn(drain_stdout(remaining_stdout, session_id)); spawn_app_shell(session_id, app_id).await