Mysterious issue with okhttp call (SocketTimeException) - retrofit

I am using Okhttp 2.5, 2.6, 2.7 with RxJava and Retrofit 2. I got some mysterious issue with okhttp call. When I made call with retrofit my Okhttp interceptor get called immediately while NetworkInterceptor called after 4 to 5 second. Sometime its more than 15 second, and leads SocketTimeoutExcpetion.
Please suggest, What should I do to solve this problem. Is there any thread blocking my call get executed?

OkHttp is behaving as it should. A SocketTimeoutException happens when the server takes longer to respond than what the client is willing to wait, and it just gives up. There is a default read timeout of 10 seconds since OkHttp 2.5 (and including the new 3.0), which would explain why you're getting the exception after 15 seconds.
You can set your own timeouts to allow your server ample time to respond:
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(20, TimeUnit.SECONDS); // connect timeout
client.setReadTimeout(20, TimeUnit.SECONDS); // socket timeout
Note that this doesn't handle the exception, it will still be thrown if the client doesn't receive a response in x seconds now. I would make sure to actually catch the exception. This would be an appropriate place to have your retry logic.
Since you're using RxJava with Retrofit, you could just add retry/retryWhen to your chain to catch and handle SocketTimeoutException errors, and maybe even mix in exponential backoff.

I know that is an old story but I seems to found a solution.
To fix SocketTimeoutException you need to setup connection pool with 0 (!) idle connections!
okBuilder.connectionPool(new ConnectionPool(0, 30, TimeUnit.SECONDS));

Related

How do I make a Vertx handler execute earlier in eventloop?

I'm using Vertx 3.5.0 and very new to it. I'm trying to cancel the code execution when a client cancels their request.
Currently it's setup to where the first thing we do is deploy a verticle to run an HttpServer, and we add all of our Routes to the Router. From here we have a handler function per route. Inside this handler I'm trying this:
routingContext.request().connection().closeHandler({
//execute logic for ending execution
});
This is the only method I've seen that actually catches the closing of the connection, but the problem is it doesn't execute the handler early enough in the eventloop. So if I have any logs in there it will look like:
...[vert.x-eventloop-thread-0].....
...[vert.x-eventloop-thread-0]..... (Let's say I cancelled the request at this point)
...[vert.x-eventloop-thread-0].....
...[vert.x-eventloop-thread-0]..... (Final log of regular execution before waiting on asynchronous db calls)
...[vert.x-eventloop-thread-0]..... (Execution of closeHandler code)
I'd like for the closeHandler code to interrupt the process and execute essentially when the event actually happens.
This seems to always be the case regardless of when I cancel the request so I figure I'm missing something about how Vertx is handling the asynchronousity.
I've tried executing the closeHandler code via a worker verticle, inside the blockingHandler from the Router object, and inside the connectionHandler from the HttpServer object. All had the same result.
The main code execution is also not executed by a worker verticle, just a regular one.
Thanks!
It seems you misunderstand what a closeHandler is. It's a callback method, that Vert.x invokes when the request is being closed. It is not way to terminate the request early.
If you would like to terminate request early, one way is to use response().close() instead.
As a footnote, I'd like to mention that Vert.x 3.5.0 is 4 years old now, and you should be upgrading to 3.9, or, if you can, to 4.0

Corda - flow timeout

According to the docs...
The call must be executed in a BLOCKING way. Flows don’t currently
support suspending to await the response to a call to an external
resource For this reason, the call should be provided with a timeout
to prevent the flow from suspending forever. If the timeout elapses,
this should be treated as a soft failure and handled by the flow’s
business logic
How do I create an initiator flow that times out if it does not receive a response in an allotted time? Are there any examples of this?
As of Corda 3, there is no mechanism for causing a flow to time out. When the docs say "the call should be provided with a timeout", this refers to the HTTP call.
The only alternative currently is to check how long the HTTP call has taken when the response is received, and throw an error in the flow if the time window is exceeded.

org.apache.http.conn.HttpHostConnectException in Apache Camel: when is it thrown?

I'm trying to wire up some exception handlers in Apache Camel, and I've got it in mind that org.apache.http.conn.HttpHostConnectException may be a good exception to attempt a few retries for rather than just logging and giving up. I've been led to believe that this is the exception we can expect if an http endpoint is temporarily down / unavailable.
Under what circumstances is HttpHostConnectException thrown? How might I simulate this circumstance to verify retry behavior?
the HttpHostConnectException isn't explicitly thrown by Camel, but is just passed back from the HttpClient execute() call (see http://hc.apache.org/httpclient-3.x/exception-handling.html)
take a look at this Camel unit test for an example of how to handle/reproduce it...
https://svn.apache.org/repos/asf/camel/trunk/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpNoConnectionRedeliveryTest.java

How to give quick response to httpRequest?

I receive httpRequest which raises long business logic (about 1 sec). I must give answer to httpSender during 0.2 sec, otherwise I receive the second httpRequest.
Now I encountered with next issue: I give httpResponse right after receiving httpRequest, but Response.End() stop working all the rest. So, to achieve this: both give quick response and process request?
I see only creating thread and processing request in other thread, but I'm afraid that Response.End() will stop a thread too.
You should handle you business logic async from your http call handling. Start a new thread which handles the bl method and continue with sending the response. Your thread will not be stopped if you start it correct.
Yeah you are right, you can send only one response for one request and doing this asynchronously won't help you because you can't hold the request until background thread finishes it. The ideal way to solve this is to break your api(server methods) in small parts and optimize your logic so it can response in expected time.
And if you are computing large data sets than Its recommended to use windows-service(or some other background mechanism) for computation and store computed data in database.
Start the request sending via Response.Flush() as soon as possible, before the long-running task is started. That will send the headers to the client immediately. Reminder: You won't be able to alter the HTTP headers after that call.

ASP .Net WebService

What happens if the webservice gets time out before the client actually gets the response.what happens if the client retries to call the webservice function before it gets the response for the previous call because of time out.
The answer depends on which SOAP client you are using, however most of them will throw some type of exception if a timeout occurs, and they usually do not automatically retry on timeout.
Webservice requests are asynchronous, so a retry (although it won't on its own) will initiate a different thread/process, which might create undesirable issues as far as business logic is concerned. If the webservice times out before the client receives the response, it will throw a timeout error to the client.

Resources