user3203425
user3203425

Reputation: 3059

How to disable retries for one connection with OkHttp?

I'm using OkHttp and want to disable connection retries on a particular api call. Is this the correct way to do it?:

mMyGlobalClient = new OkHttpClient();

....

public void makeConnection(...) {

    OkHttpClient client = null;
    if (disableRetries) {
        OkHttpClient clone = mMyGlobalClient.clone();
        clone.setRetryOnConnectionFailure(false);
        client = clone;
    } else {
        client = mMyGlobalClient;
    }

    client.newCall(...);
}

The idea comes from this post:

https://github.com/square/okhttp/pull/1259#issue-53157152

Most applications won't want to disable retry globally. Instead, use clone() to get an OkHttpClient for a specific, non-idempotent request, then configure that client with the setting.

The reason I want to disable retries for this one call is because it can be destructive if it gets handled twice by my server:

https://github.com/square/okhttp/pull/1259#issuecomment-68430264

Thank you

Upvotes: 5

Views: 8500

Answers (3)

Majedur
Majedur

Reputation: 3242

In addition, I have solved the issue in retrofit2.

To prevent retry you have to use .retryOnConnectionFailure(false) method with OkHttpClient.

Sample code:

OkHttpClient okHttpClient= null;
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(2, TimeUnit.MINUTES)
                .readTimeout(2, TimeUnit.MINUTES)
                .writeTimeout(2, TimeUnit.MINUTES)
                .retryOnConnectionFailure(false)
                .cache(null)//new Cache(sContext.getCacheDir(),10*1024*1024)
                .build();

In previous version have some bugged and fixed after retrofit:2.1.0

So you should use updated version of retrofit2 and okhttp3:

implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
implementation 'com.squareup.okhttp3:okhttp:3.4.1' 

Issue discussion:

https://github.com/square/okhttp/pull/1259#issuecomment-68430264

Upvotes: 3

Christian
Christian

Reputation: 747

use call.cancel();

with final Call call = client.newCall(request);

If you want to limit the retries, you can use :

if (responseCount(response) >= 3) {
    call.cancel(); // If we've failed 3 times, give up.
}

Upvotes: 0

Vitaly Zinchenko
Vitaly Zinchenko

Reputation: 4911

Yes, this is the right way.

By the way, if you don't mind, you could write it a little simpler

mMyGlobalClient = new OkHttpClient();

....

public void makeConnection(...) {

    OkHttpClient client = null;
    if (disableRetries) {
        client = mMyGlobalClient.clone();
        client.setRetryOnConnectionFailure(false);
    } else {
        client = mMyGlobalClient;
    }

    client.newCall(...);
}

Upvotes: 9

Related Questions