How to prevent hangs on SocketInputStream.socketRead0 in Java?
apache-httpclient-4.x, http, java, sockets, timeout
Solution
For Apache HTTP Client (blocking) I found best solution is to getConnectionManager(). and shutdown it.
So in high-reliability solution I just schedule shutdown in other thread and in case request does not complete I'm shutting in down from other thread
Problem
Performing millions of HTTP requests with different Java libraries gives me threads hung on: `java.net.SocketInputStream.socketRead0()` which is a `native` function. I tried to set up the Apache Http Client and `RequestConfig` to have timeouts on (I hope) everythig that is possible but still, I have (probably infinite) hangs on `socketRead0`. How to get rid of them? The hung ratio is about ~1 per 10000 requests (to 10000 different hosts) and it can last probably forever (I've confirmed thread hung as still valid after 10 hours). JDK 1.8 on Windows 7. My `HttpClient` factory: ``` SocketConfig socketConfig = SocketConfig.custom() .setSoKeepAlive(false) .setSoLinger(1) .setSoReuseAddress(true) .setSoTimeout(5000) .setTcpNoDelay(true).build(); HttpClientBuilder builder = HttpClientBuilder.create(); builder.disableAutomaticRetries(); builder.disableContentCompression(); builder.disableCookieManagement(); builder.disableRedirectHandling(); builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy()); builder.setDefaultSocketConfig(socketConfig); return HttpClientBuilder.create().build(); ``` My `RequestConfig` factory: ``` HttpGet request = new HttpGet(url); RequestConfig config = RequestConfig.custom() .setCircularRedirectsAllowed(false) .setConnectionRequestTimeout(8000) .setConnectTimeout(4000) .setMaxRedirects(1) .setRedirectsEnabled(true) .setSocketTimeout(5000) .setStaleConnectionCheckEnabled(true).build(); request.setConfig(config); return new HttpGet(url); ``` OpenJDK `socketRead0` source Note: Actually I have a "trick": I can schedule `.getConnectionManager().shutdown()` in other `Thread` with a cancellation of the `Future` if request finished properly. But, it is deprecated and also it kills whole `HttpClient`, not just that single request.