From 6c6225d8319d661e22e3fd551f3be79f792e8a22 Mon Sep 17 00:00:00 2001 From: JohannesItten Date: Tue, 7 Jul 2026 22:39:09 +0300 Subject: [PATCH] fix: don't double-send status to command requester MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit load_graph/stop_node/start_node each called notify() (push to all clients) and then sent a direct response — the requesting client got two identical messages, breaking test recv sequencing. Use thread_local tl_requester to skip the requesting connection in the push. notify() is called synchronously from the command, so the thread_local is visible from the status_cb. Other clients still receive the push; the requester gets only the direct response. Co-Authored-By: Claude Sonnet 4.6 --- studio-manager/main.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/studio-manager/main.cpp b/studio-manager/main.cpp index df7acca..b27e0b1 100644 --- a/studio-manager/main.cpp +++ b/studio-manager/main.cpp @@ -45,11 +45,17 @@ int main(int argc, char* argv[]) { std::mutex ws_mutex; std::unordered_set clients; - // Push status to every connected client (called without manager mutex held). + // Push status to every connected client except the one whose command triggered + // the change — that client gets the direct response from the handler instead. + // tl_requester is thread-local: notify() is called synchronously from within + // the manager command, so it runs on the same thread as onmessage. + thread_local crow::websocket::connection* tl_requester = nullptr; + manager.on_status_change([&](nlohmann::json status) { std::lock_guard lk(ws_mutex); const std::string msg = status.dump(); - for (auto* c : clients) c->send_text(msg); + for (auto* c : clients) + if (c != tl_requester) c->send_text(msg); }); CROW_WEBSOCKET_ROUTE(app, "/ws") @@ -76,6 +82,7 @@ int main(int argc, char* argv[]) { nlohmann::json response; const std::string type = j.value("type", ""); + tl_requester = &conn; try { if (type == "load_graph") response = manager.load_graph(j.at("graph")); else if (type == "stop_node") response = manager.stop_node(j.at("id")); @@ -85,6 +92,7 @@ int main(int argc, char* argv[]) { } catch (const std::exception& e) { response = {{"type","error"},{"message", e.what()}}; } + tl_requester = nullptr; conn.send_text(response.dump()); });