Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Write Retry Interceptor For Data Stream In OkHttp?

Or thinking the interceptor for this scenario applicable ?

Our app using OkHttp for downloading files (new version of app, daily databases etc.)

Sometimes server fails just while the app streaming bytes (btw the problem is, recvfrom failed: ECONNRESET)

So to fix this case i just wanted to write OkHttp retry interceptor. But seems this is appropriate for operations which aren't streaming.

Is there a solution(like interceptor) to handle this case ?


To make more clear exposition

0%==============================100% (Just started streaming)

0%==============================100% (10% completed)

0%==============================100% (20% completed)

0%==============================100% (ECONNRESET - Connection reset by peer)

At just this point, streaming gets stopped. The thing i'm wishing from OkHttp is recognizing this situation then starting the stream from scratch (not from 20%)


Related code here, pay attention to comments

 Call call = client.newCall(new Request.Builder().url(url).get().build());
 Response response = call.execute();
 // PROBLEM DOES NOT OCCUR THERE
 // PROBLEM DOES NOT OCCUR THERE
 // PROBLEM DOES NOT OCCUR THERE
 if (response.code() == 200 || response.code() == 201) {
     InputStream inputStream = null;
     try {
         long downloaded = 0;
         byte[] buff = new byte[1024 * 4];
         inputStream = response.body().byteStream();
         long target = response.body().contentLength();
         while (true) {
             // EXCEPTION OCCURS THERE
             // EXCEPTION OCCURS THERE
             // EXCEPTION OCCURS THERE
             int read = inputStream.read(buff);
             if (read == -1) {
                 break;
             }
             downloaded += read;
         }
         ...
     } catch (IOException e) {
         // EXCEPTION SAYS 
         // ECONNRESET - Connection reset by peer
         ...
     }
}
like image 427
blackkara Avatar asked May 03 '18 13:05

blackkara


People also ask

How does OkHttp interceptor work?

Interceptors, according to the documentation, are a powerful mechanism that can monitor, rewrite, and retry the API call. So, when we make an API call, we can either monitor it or perform some tasks. In a nutshell, Interceptors function similarly to airport security personnel during the security check process.

What is OkHttp logging interceptor?

Android OkHttp Logging interceptor Interceptors are used to intercept OkHttp calls. The reason to intercept could be to monitor, rewrite and retry calls. It can be used for outgoing request or incoming response both.

What is an interceptor in retrofit?

According to documentation, Interceptors are a powerful mechanism that can monitor, rewrite, and retry the API call. So basically, when we do some API call, we can monitor the call or perform some tasks.


2 Answers

You can write a custom Interceptor like below:

OkHttp has Interceptors. You need a custom Interceptor like one below:

public class CustomResponseInterceptor implements Interceptor {

    private final String TAG = getClass().getSimpleName();

    @Override
    public Response intercept(Object object) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        if (response.code() != 200//Your error code here,) {
           //Cancel your Request here
            return something;
        }
        Log.d(TAG, "INTERCEPTED:$ " response.toString());
        return response;
    }

The code shown is extracted from this Medium Article on Interceptors.
You can also look at this library which implements Retry Interceptors, But you can modify it for your use.

like image 87
Ganesh Avatar answered Sep 30 '22 17:09

Ganesh


When ECONNRESET - Connection reset by peer occurs why don't you cancel your ongoing call in your catch block and start a new network call for the same file

catch (IOException e) {
         // EXCEPTION SAYS 
         // ECONNRESET - Connection reset by peer
         ...
         call.cancel();//something like this
         startDownloadingFromScratch();//new network request to start from scratch  
     }
like image 21
Vicky Avatar answered Sep 30 '22 17:09

Vicky