DectrisSimplonClient: separate connections for commands and status reads

Commands and configuration writes (initialize, disarm, threshold change) can
take minutes. With one shared connection a status poll waited behind them;
now commands/config writes go through one kept-alive client and status/config
reads through another, each with its own mutex and fixed timeouts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-08 22:53:01 +02:00
co-authored by Claude Opus 5.5
parent 9807bc40df
commit 41411b51b8
3 changed files with 46 additions and 24 deletions
+20 -1
View File
@@ -4,13 +4,16 @@
#include <catch2/catch_all.hpp>
#include <httplib.h>
#include <nlohmann/json.hpp>
#include <atomic>
#include <chrono>
#include <mutex>
#include <set>
#include <thread>
#include "../detector_control/DectrisSimplonClient.h"
// A minimal SIMPLON server: the detector state and error list, and a disarm command that fails.
// A minimal SIMPLON server: the detector state and error list, a disarm command that fails and a
// cancel command that takes 2 s.
TEST_CASE("DectrisSimplonClient_MockServer", "[detector]") {
httplib::Server server;
std::mutex m;
@@ -34,6 +37,13 @@ TEST_CASE("DectrisSimplonClient_MockServer", "[detector]") {
res.set_content("disarm refused", "text/plain");
});
std::atomic<bool> cancel_running = false;
server.Post("/detector/api/1.8.0/command/cancel", [&](const httplib::Request &, httplib::Response &res) {
cancel_running = true;
std::this_thread::sleep_for(std::chrono::seconds(2));
res.set_content("", "text/plain");
});
const int port = server.bind_to_any_port("127.0.0.1");
REQUIRE(port > 0);
struct ServerThread {
@@ -53,6 +63,15 @@ TEST_CASE("DectrisSimplonClient_MockServer", "[detector]") {
CHECK(client.GetErrorStatus() == R"(["overheating"])");
// A long command does not hold up status polls
std::thread cancel([&client] { client.CancelAcquisition(); });
while (!cancel_running)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
auto t0 = std::chrono::steady_clock::now();
CHECK(client.GetState() == SimplonState::Idle);
CHECK(std::chrono::steady_clock::now() - t0 < std::chrono::milliseconds(500));
cancel.join();
// Failures carry the HTTP status and the body the DCU sent
{
std::lock_guard lg(m);