Retrofit first request takes exact OkHttpClient timeout - android

I'm using Retrofit and OkHttpClient to build a Rest API on Android.
Some time ago, i had noticed the very first request made by the api always take way longer to process than all others... At begining i didn't care because it was an acceptable time.
But suddenly the request time jumped to 60 SECONDS
All this time is waste client side, since monitoring the server i see that the processing time takes less than 1 seconds...
I was wondering what change I made that could cause such high impact, then I realized that i changed the connection timeout of OkHttp.
I had changed the value from 10 seconds to 60 seconds just for testings...
I made some experiments setting the connectTimeout to many others values and ALWAYS the first request takes the time sighly above the timeout
Does anyone know what may cause this weird behavior? how to solve it?
PS. I needed to test the api on a desktop and this problem didnt occur, i mean it is only happening on android devices [i tried several] what is the cause?

https://medium.com/inloopx/okhttp-is-quietly-retrying-requests-is-your-api-ready-19489ef35ace
It is likely failing on the first few requests and timing out. OkHTTP is automatically retrying.
builder.retryOnConnectionFailure(false);
Try turning off the auto retry and see what happens.
https://www.reddit.com/r/gfycat/comments/5y2dkm/psa_for_android_devs_how_to_work_around_ipv6/
It is likely an ipv4 vs ipv6 problem. This code prioritizes ipv4 addressses.

You could configure an EventListener in your OkHttpClient and use that to see how the time is spent.

Related

Android First Volley request takes longer

so I've made an Android application which retrieves data from an API using Volley Framework with a GET request. The problem is that the first request that I make takes around 10 seconds to respond and then if I relaunch the app this same request only takes like 2-3 seconds. If I wait like 2 hours then I restart the app it again takes 10 seconds. I was wondering why this first request takes so long.
Thanks for your answers
Thanks to Ivan Wooll I found the problem.
As explained in this answer, I'm using Azure App Service and by default the website is taken down after 20 minutes of inactivity and it has to restart after that, that's why the first request takes so long.

How to fix "your api request count has exceeded?" for tmdb.org?

My code was working fine initially, then All of a sudden I'm not able to display posters on my app. I'm getting this particular error.
I've removed almost all while(true) loops. Please help.
You are probably making too many API requests.
From the TMDB.org FAQ:
We currently rate limit requests to 30 requests every 10 seconds.
You should make sure your app never uses more than that. How you implement this is up to you, but you could keep track of a request counter that:
decrements every time you make a request
resets to 30 or so every ten seconds
only allows requests to continue if it is positive
In general, you should try to query the API as little as possible: cache results in your app as much as you can.

Android Volley: Pros/Cons overriding DefaultRetryPolicy of Request

By default Volley request timeout is set to 2500ms and it makes 1 retry per request.
I wonder if it's a good thing to override it, let's say request timeout is set to 5000ms and 2 retries per request?
What are the reasons default timeout is 'just' 2.5 sec?
Why 'only one' retry? It seems not enough, but perhaps there are good reasons hiding common best practises.
I'm tuning to considerations in the level of http, networking, routing etc. (NOT Android UI/UX).
EDIT: Example - If I set the timeout to 5 sec, is it possible waste of time because in some http level if the connection is NOT OK so the average response time to know this is only 2 sec? What are these http details I need to consider while overriding DefaultRetryPolicy?
Thanks,

Calling a Web Service using ksoap2 is very slow (just sometimes)

In my application, I call some Web Serices (WS) using ksoap2 library and almost all o the time it works fast. But sometimes, the call of the WS is very slow.
I have a code like this:
beforecall = System.currentTimeMillis();
androidHttpTransport1.call(NameSpaces.NAMESPACE+UserWSMethodName.GETUSERINFO,envelope1);
Log.d("soapdebug","call duration="+(System.currentTimeMillis()-beforecall));
And generally I get 1 or 2 seconds (Max), but sometimes I get 11 seconds... And when the calls are too slow, it happens for all WS, and after a while (hours, for instance) it comes back to normal and become fast...
In wireshark, I see that for each call, the time elapsed between the call() method is invoked and the time where the server establish the the TCP connection with a [SYN] packet, is about 10 seconds so it is during this time that the time is spent, but I don't understand why this happen just sometimes.
What could be causing the problem?
It could be a device configuration?
What I have made to solve this problem was just reboot the router where the mobile device is connected.

Effectively caching data uploads in Android

I have implemented a queue service in Android that will change states based on queue and wifi/data connectivity events.
I queue transactions to be posted to a remote url. If the device has a data or wifi connection, it will iterate the queue and post data to the url until the queue is empty, or there is a disconnect event.
I can login to my app, enable airplane mode, generate data, turn airplane mode off, and the transaction are posted. No slow down, even with thousands of transactions. (I was trying to pish it a bit)
Enter: low reception!
My app slows down enormously when the 3G reception is low. (Yes, all uploading happens off the ui thread.) It seems that the cause of this slow down has to do with the post to the server taking a very long time to happen and sometimes just failing.
My question is, how can I solve this? Check for signal quality? Poll a known address? How do other apps, such as Gmail solve this? This must be a common scenario!
Well if you could potentially have thousands of tasks that all need to be executed, then surely they should be managed. Have you thought about implementing your own ThreadPoolExecutor? The documentation is very good and the class is easy to understand, but if you need examples try these sites:
http://www.javamex.com/tutorials/threads/ThreadPoolExecutor.shtml
http://javabeanz.wordpress.com/2010/02/19/threadpoolexecutor-basics/
The benefit of this is that you can limit the maximum number of threads you are spawning, so you shouldn't get a system-wide slow down if you limit your thread count to a reasonable number (For Android I'd recommend no more than 20).
May be do some fine-tuning of socket and conenction timeout? Thus, if your connection is slow and stalled, timeout will occur and transmission will fail.
After connection/sending is failed you can retry transmission later or do something else.
To adjust timeouts you can use the following code:
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 30 * 1000);
HttpConnectionParams.setSoTimeout(httpParameters, 15 * 1000);
HttpClient client = DefaultHttpClient(httpParameters);
// use client...
We have similar situation for our application. We have considered signal issues to be a reality and one that can happen any time. One of the point that we follow is not to remove any content from device unless we get a functional confirmation from server and just base on http status code.As in the slow network or the cases where we can lose signal suddenly, while we may have posted our content, there were many cases where data was received only partially. And so we decided to let server know device by some manner [result through some http get based request calls made by device] that content has been received.
More than performance or checking the network, the question that you asked, we needed such behavior for our application robustness.
You should check out using HTTP Range headers, for example like here.
The server should write payload to disk while reading, and handle disconnects. The client cannot know how many bytes payload actually reached the server, so it needs to sync up with the server every time there has been a network error. Dont forget to handle battery and user issues too ;-)
If you want to wait for a better signal, perhaps the SignalStrength class, with its getCdmaDbm, getEvdoDbm, and getGsmSignalStrength methods, is what you are looking for.
Check out this:
http://www.youtube.com/watch?v=PwC1OlJo5VM#!
advanced coding tips and tricks, bandwidth-saving techniques, implementation patterns, exposure to some of the lesser-known API features, and insight into how to minimize battery drain by ensuring your app is a good citizen on the carrier network.

Categories

Resources