test: fix flaky tests caused by worker thread pollution#88
Merged
Conversation
Add res.keep_alive = false to the first response in the 'updates query parameters on reconnection' test. Without this, the empty chunked response leaves the TCP connection open via HTTP keep-alive, creating a race condition between WEBrick and the HTTP gem during fast reconnection. Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
- Test 1118: send SSE comment data before closing (matches pattern of non-flaky reconnection tests that send actual data) - Test 1329: use larger reconnect_time (0.25s) to avoid race in rapid 500 retries within the connect loop Both tests flake with nil query_string due to a timing race between the HTTP gem and WEBrick during ultra-fast (10ms) reconnection. Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Use EOF-based reconnection (stream close) instead of 500-based reconnection for the 'each reconnection attempt' test. The HTTP gem has a race condition when reusing a closed client within the same connect loop on Ruby 3.2, causing nil query strings. Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
The SSE client's worker thread is fire-and-forget (Thread.new without join). After client.close sets @stopped, the worker thread may still make one more reconnection attempt before checking the flag. When the next test reuses the same WEBrick port, this phantom request arrives with no query params, causing nil assertions. Fix: add sleep 0.1 in with_client after close to let the worker thread terminate before the next test starts its server on the same port. Also reverts the unnecessary reconnect_time increases and uses EOF-based reconnection (stream close) instead of 500 errors for the multi-reconnection test, matching the pattern of all stable tests. Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Use Thread.join to reliably wait for SSE worker threads to terminate before the next test starts. Applies to both client_spec and headers_spec with_client helpers. Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
Co-Authored-By: rlamb@launchdarkly.com <4955475+kinyoklion@users.noreply.github.com>
keelerm84
approved these changes
Jun 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes flaky test failures across
client_spec.rbandheaders_spec.rbcaused by SSE worker thread pollution between tests.Root cause:
SSE::Clientspawns a fire-and-forget worker thread (Thread.new { run_stream }) that is not joined onclose. Afterclient.closesets@stopped, the worker thread may still complete one more reconnection attempt before checking the flag. Since all tests reuse port 50000, this phantom request hits the next test's WEBrick server — arriving without query params or with stale headers, causingnilassertions.Fix: In both
with_clienthelpers, join the named'LD/SSEClient'thread after close:Also uses EOF-based reconnection (stream close) instead of HTTP 500 responses for the multi-reconnection test, matching the pattern of all stable tests.
Verified: 5/5 CI passes, 20/20 local runs on Ruby 3.2, 20/20 on Ruby 3.3.
Link to Devin session: https://app.devin.ai/sessions/e40ffc3296dd45648f86ac10c42b6da5
Requested by: @kinyoklion
Note
Low Risk
Spec-only changes; no production library behavior is modified.
Overview
Stabilizes end-to-end specs in
client_spec.rbandheaders_spec.rbby ensuring each example fully tears down theSSE::Clientworker before the shared stub server port is reused.Both
with_clienthelpers nowjoin(0.01s)** any thread named **LD/SSEClient** after **client.close`, so a lingering reconnect cannot hit the next example’s WEBrick handler with wrong query strings or headers.Two dynamic query_params reconnection examples no longer force reconnect via HTTP 500; they close the event stream (minimal SSE comment payloads) instead, aligning with other stable reconnect tests.
Reviewed by Cursor Bugbot for commit 27e0006. Bugbot is set up for automated code reviews on this repo. Configure here.