VishnuPriyaChandraSekar commented on code in PR #4626:
URL: https://github.com/apache/solr/pull/4626#discussion_r3555165657
##########
solr/solrj/src/test/org/apache/solr/client/solrj/impl/LB2SolrClientTest.java:
##########
@@ -405,6 +405,9 @@ private class TimeoutZombieTestContext implements
AutoCloseable {
new HttpJettySolrClient.Builder()
.withConnectionTimeout(1000, TimeUnit.MILLISECONDS)
.withIdleTimeout(1, TimeUnit.MILLISECONDS)
+ // override the infinite request timeout with idle timeout to
ensure idle requests
+ // times out.
Review Comment:
The idleTimeout does not seem to be working. To be honest, I could not
reason out. I sought out Gemini for assistance. Here is the explanation
The test gets stuck because of the behavior of the ServerSocket acting as a
blackhole.
Here is exactly why an idleTimeout is not enough to break the hang in this
specific scenario:
## 1. Connection-Level vs. Request-Level Lifecycle
* idleTimeout belongs to the connection: It monitors activity on an already
established, active HTTP connection. It only ticks down when a connection is
sitting open in a pool, waiting for a new request to be sent, or between packet
bursts on a persistent stream.
* requestTimeout belongs to the HTTP exchange: It monitors the overall time
given to the client to send a request and receive a complete response.
## 2. The Blackhole TCP Handshake Trap
In your TimeoutZombieTestContext, you instantiate new ServerSocket(0).
1. When the Solr client attempts to connect to blackholePort, the
operating system's underlying TCP stack automatically completes the TCP 3-way
handshake (SYN -> SYN-ACK -> ACK) in the background.
2. The connection is successfully established and moved into the OS
listen backlog, even though your Java code never calls blackhole.accept().
3. Because the TCP connection is successfully established, the
.withConnectionTimeout(1000) condition is satisfied and stops tracking.
## 3. Why idleTimeout Never Triggers
Once the connection is open, the client sends its HTTP request payload (the
QueryRequest).
* From the client's perspective, it successfully wrote data to the socket
stream.
* The client is now in a blocking read() state, waiting for the server to
reply.
* In many HTTP client implementations (including Jetty's client under the
hood), the idleTimeout configuration is suspended or overridden during an
active, outbound request execution phase, or it expects the server to actively
close the connection.
* Because the blackhole ServerSocket just sits there and never reads the
data, never responds, and never closes the socket, the client thread hangs
indefinitely waiting for a response header that will never arrive.
## How requestTimeout Fixes It
By uncommenting .withRequestTimeout(1000), you introduce a client-side
watchdog timer. This timer starts the moment the execution begins. It does not
care about TCP states or whether data was sent; if 1000ms passes without a
complete HTTP response, it forcefully aborts the request execution, throws a
TimeoutException, and allows your catch (Exception e) block to trigger so the
test can advance to assertZombieState().
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]