Hunter Presnall created HTTPCORE-528:
----------------------------------------
Summary: Infinite loop on server disconnect
Key: HTTPCORE-528
URL: https://issues.apache.org/jira/browse/HTTPCORE-528
Project: HttpComponents HttpCore
Issue Type: Bug
Components: HttpCore NIO
Affects Versions: 4.4.9
Environment: bare metal Ubuntu 16.04 with kernel 4.4;
openjdk1.8.0_172_x64 and Oracle jdk1.8.0_162_x64
CentOs Docker container with 3.10; openjdk1.8.0_172_x64
macOS 10.13.5; openjdk1.8.0_172_x64
Reporter: Hunter Presnall
Attachments: httpdebug.log
I am seeing HTTP NIO client get into an infinite loop after the server
disconnections the connection. See the log output attached; note some content
removed for privacy.
Note that the HttpAsyncClient has returned the response and the application has
completely processed it. The client maintains the connection, as expected,
since the response included `Keep-Alive: timeout=5`. Five seconds after
everything is complete, the _server_ closes the TCP connection. The client
reacts accordingly: the selector wakes up, does a read of -1 bytes, closes the
session and sets a 1 second timeout to close the connection in.
The infinite loop occurs because the selector.select() call _constantly_
returns in AbstractIOReactor.execute()
readyCount == 1, so events are processed
processEvent() notes the key is readable and calls:
session.resetLastRead()
readable(key);
Because resetLastRead() is constantly updated, the 1 second timeout is never
reached and AbstractIOReactor.timeoutCheck() can never call sessionTimedOut()
or close the connection.
Note the entire time this is happening, netstat shows the connection is in
CLOSE_WAIT state. The infinite loop continues until the OS keepalive timeout is
reached and the connection is cleaned by the OS.
I am not sure if this epoll / selector behavior is expected or not. However, I
have replicated this issue in multiple environments. It seems like the async
client should handle this by detecting the condition and closing the connection.
Other notes from this infinite loop state:
SSLIOSession.updateEventMask() never closes the session either since the state
remains `CLOSING`
AbstractIODispatch.inputReady() _does not_ read any data from the connection
since ssliosession.isAppInputReady() evaluates to false.
SelectionKeyImpl.interestOps remains 1 (`OP_READ`)
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]