Here's my configuration:
httpClient = new OkHttpClient.Builder()
.callTimeout(Duration.ofSeconds(60))
.connectTimeout(Duration.ofSeconds(60))
.readTimeout(Duration.ofSeconds(60))
.writeTimeout(Duration.ofSeconds(60))
.build();
I have a multithreaded process that uses this client. Few seconds after running I'm getting:
java.net.SocketTimeoutException: timeout
at okio.Okio$4.newTimeoutException(Okio.java:232)
at okio.AsyncTimeout.exit(AsyncTimeout.java:286)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:241)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:358)
How is it possible if I configured the timeouts to 60 seconds?
EDIT:
Even adding a custom dispatcher didn't help:
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(Integer.MAX_VALUE);
dispatcher.setMaxRequestsPerHost(Integer.MAX_VALUE);
TECHNICAL DETAILS:
As opposed to what I've said, I'm running both the client and the server on Linux machines:
Client's machine: net.ipv4.tcp_keepalive_time = 7200
Server's machine: net.ipv4.tcp_keepalive_time = 7200
As you may suspect based on the name, the SocketTimeoutException is thrown when a timeout occurs during a read or acceptance message within a socket connection. Throughout this article we'll explore the SocketTimeoutException in more detail, starting with where it resides in the overall Java Exception Hierarchy.
Root Cause This problem is caused by an environment issue, such as: Server is trying to read data from the request, but its taking longer than the timeout value for the data to arrive from the client. Timeout here would typically be tomcat connector -> connectionTimeout attribute.
You are most likely affected by the socket timeouts imposed by the operating system. Java can't extend them since the sockets are managed by the system. As per this great answer, "Changing TCP Timeouts" section:
Unfortunately since TCP connections are managed on the OS level, Java does not support configuring timeouts on a per-socket level such as in
java.net.Socket
. I have found some attempts to use Java Native Interface (JNI) to create Java sockets that call native code to configure these options, but none appear to have widespread community adoption or support.
For MacOS you have to look at sysctl net.inet.tcp
output and see what are the system limits.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With