Skip to content

Commit 164f642

Browse files
committed
Fix SSE tests failing on Linux
- Fix httplib::Client thread-safety issue: create clients in the same thread that uses them (Linux-specific behavior) - Fix SSE server startup probe: track actual data receipt instead of checking Result object (cancelled requests appear as errors to httplib) The root cause was that httplib::Client is not thread-safe when created in one thread and used in another on Linux. Additionally, when an SSE content receiver returns false to cancel, httplib reports the result as an error even though data was successfully received.
1 parent 669b0c4 commit 164f642

3 files changed

Lines changed: 25 additions & 17 deletions

File tree

‎examples/streaming_demo.cpp‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,15 @@ int main()
4444
std::atomic<bool> sse_connected{false};
4545
std::string session_id;
4646

47-
httplib::Client cli("127.0.0.1", port);
48-
cli.set_connection_timeout(std::chrono::seconds(10));
49-
cli.set_read_timeout(std::chrono::seconds(20));
47+
// NOTE: httplib::Client must be created in the same thread that uses it on Linux
5048
std::thread sse_thread(
51-
[&]()
49+
[&, port]()
5250
{
51+
// Create client inside thread - httplib::Client is not thread-safe across threads on Linux
52+
httplib::Client cli("127.0.0.1", port);
53+
cli.set_connection_timeout(std::chrono::seconds(10));
54+
cli.set_read_timeout(std::chrono::seconds(20));
55+
5356
auto receiver = [&](const char* data, size_t len)
5457
{
5558
sse_connected = true;

‎src/server/sse_server.cpp‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -479,18 +479,22 @@ bool SseServerWrapper::start()
479479

480480
// Wait for server to be ready by probing the SSE endpoint briefly.
481481
// This reduces flakiness in constrained environments.
482+
// NOTE: When the content receiver returns false to cancel, httplib reports the
483+
// Result as an error even though data was received. Track actual data receipt.
482484
for (int attempt = 0; attempt < 20; ++attempt)
483485
{
486+
bool received_data = false;
484487
httplib::Client probe(host_.c_str(), port_);
485488
probe.set_connection_timeout(std::chrono::seconds(2));
486489
probe.set_read_timeout(std::chrono::seconds(2));
487-
auto res = probe.Get(sse_path_.c_str(),
488-
[&](const char*, size_t)
489-
{
490-
// Cancel after first chunk to indicate readiness
491-
return false;
492-
});
493-
if (res)
490+
probe.Get(sse_path_.c_str(),
491+
[&](const char*, size_t)
492+
{
493+
// Cancel after first chunk to indicate readiness
494+
received_data = true;
495+
return false;
496+
});
497+
if (received_data)
494498
break;
495499
std::this_thread::sleep_for(std::chrono::milliseconds(50));
496500
}

‎tests/server/sse.cpp‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,22 @@ int main()
5555
return 1;
5656
}
5757

58-
// Create HTTP clients: one dedicated to SSE stream, one for POST requests
59-
httplib::Client sse_client("127.0.0.1", port);
60-
sse_client.set_read_timeout(std::chrono::seconds(20));
61-
sse_client.set_connection_timeout(std::chrono::seconds(10));
62-
6358
std::atomic<bool> sse_connected{false};
6459
std::atomic<int> events_received{0};
6560
Json received_event;
6661
std::mutex event_mutex;
6762
std::string session_id;
6863

6964
// Start SSE connection in background thread (retry a few times for robustness)
65+
// NOTE: httplib::Client must be created in the same thread that uses it on Linux
7066
std::thread sse_thread(
71-
[&]()
67+
[&, port]()
7268
{
69+
// Create client inside thread - httplib::Client is not thread-safe across threads on Linux
70+
httplib::Client sse_client("127.0.0.1", port);
71+
sse_client.set_read_timeout(std::chrono::seconds(20));
72+
sse_client.set_connection_timeout(std::chrono::seconds(10));
73+
7374
// Give server a moment to fully initialize before first connection attempt
7475
std::this_thread::sleep_for(std::chrono::milliseconds(100));
7576

0 commit comments

Comments
 (0)