Repository navigation
THRIFT-5779: Keep TServerSocket accepting after aborted connections and descriptor exhaustion - #3977
Open
slachiewicz wants to merge 1 commit into
Open
slachiewicz wants to merge 1 commit into
slachiewicz wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The tests introduce a portability failure and do not cover key connection-error and backoff behavior.
Review effort: Balanced
Findings: 1
Open (3)
What changed in this PR
Improves C++ server resilience by retrying transient accept() failures instead of terminating the server loop.
Changes:
- Classifies connection and resource-exhaustion errors.
- Adds interruptible exponential retry backoff and rate-limited logging.
- Adds descriptor-exhaustion and interruption tests.
| File | Description |
|---|---|
lib/cpp/src/thrift/transport/TServerSocket.cpp |
Implements error classification, retry, and backoff behavior. |
lib/cpp/src/thrift/transport/TServerSocket.h |
Stores logging throttle state. |
lib/cpp/test/TServerSocketTest.cpp |
Tests recovery and interruption during descriptor exhaustion. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
slachiewicz
force-pushed
the
THRIFT-5779
branch
from
October 1, 2026 05:46
339640c to
5534aca
Compare
…ilure Client: cpp When accept() failed with EMFILE, TServerFramework::serve() stopped for good. acceptImpl() now waits out running out of descriptors or memory, backing off from 5 ms to 1 s and staying interruptible, and goes back to poll() when the error belongs to the one connection. Linux keeps that connection queued, so retrying without the wait would spin. Neither case is logged per attempt, because a peer can cause both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
slachiewicz
force-pushed
the
THRIFT-5779
branch
from
October 2, 2026 21:34
5534aca to
f02dc98
Compare
This branch has not been deployed
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.


TServerSocket::acceptImpl()threwUNKNOWNon anyaccept()failure, andTServerFramework::serve()then stops accepting for good. A port scanner ornc -zaborting a connection before it is accepted (ECONNABORTED) is enough to take the server down, as THRIFT-5779 reports; so is running out of descriptors (EMFILE), and the server stays down after they free up.Now:
ECONNABORTED,EPROTO, and on LinuxEPERMand the network errors accept(2) says to treat likeEAGAIN): back topoll();EMFILE,ENFILE,ENOBUFS,ENOMEM): back off from 5 ms to 1 s and retry, still interruptible;Both retried classes are logged at most once a minute, so a listening socket that fails persistently (for example
EOPNOTSUPPon a non-stream socket passed in by descriptor) still shows up in the log. TheEINTRlimit onpoll()applies per accept attempt, so signals during a longEMFILEepisode do not end it.The backoff matters on Linux, which keeps the connection queued after
EMFILE, so the listening socket stays readable; macOS drops it. The tests send a byte after connecting becauselisten()setsTCP_DEFER_ACCEPT. Replaces #2964, which retried every error without waiting. The poll loop is only re-indented;git diff -wshows the change. The error classes and the backoff step are inTServerSocketErrors.h, namespacedetail: installed with the other headers, no compatibility promise.TNonblockingServerusesTNonblockingServerSocketand is not changed.Verified: the two descriptor-exhaustion tests → 3 failures on master, pass with the change on macOS arm64.
Verified: changing the 1 s cap or dropping
ECONNABORTEDfrom the connection errors →test_accept_backoff_doubles_up_to_one_secondandtest_accept_error_classesfail.Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com