Как избежать таймаута чтения при запросе всех файлов? (Google drive api)


У меня есть приложение для дисков, которое запрашивает все файлы, которые не уничтожены. Но иногда он выдает исключение IOexception с таймаутом чтения. Есть ли способ избежать этого?

Это ошибка, которую я получаю:

Произошла ошибка: java. net. SocketTimeoutException: Read timed out

Возможно, мой экспоненциальный откат реализован неправильно.

Вот код, который я использую для получения файлов:

private static List<File> retrieveAllNoTrashFiles(Drive service) throws IOException, InterruptedException {
    List<File> result = new ArrayList<File>();
    Files.List request = service.files().list().setQ("trashed = false").setMaxResults(1000);
    do {
        try {
            FileList files =executeRequest(service,request);
            result.addAll(files.getItems());
            request.setPageToken(files.getNextPageToken());
        } catch (IOException e) {       //here I sometimes get the read timeout
            System.out.println("An error occurred: " + e);
            request.setPageToken(null);
        }
    } while (request.getPageToken() != null
            && request.getPageToken().length() > 0);

    return result;
}

private static FileList executeRequest(Drive service,Files.List request) throws IOException, InterruptedException {
    Random randomGenerator = new Random();
    for (int n = 0; n < 5; ++n) {
        try {
            return(request.execute());
        } catch (GoogleJsonResponseException e) {
            if (e.getDetails().getCode() == 403
                    && (e.getDetails().getErrors().get(0).getReason().equals("rateLimitExceeded")
                    || e.getDetails().getErrors().get(0).getReason().equals("userRateLimitExceeded"))) {
                // Apply exponential backoff.
                Thread.sleep((1 << n) * 1000 + randomGenerator.nextInt(1001));
            } 
             //else {
                // Other error, re-throw.
               // throw e;
           // }
        }
    }catch(SocketTimeoutException e){
            Thread.sleep((1 << n) * 1000 + randomGenerator.nextInt(1001));
        }
    System.err.println("There has been an error, the request never succeeded.");
    return null;
}
3 3

3 ответа:

Экспоненциальный откат срабатывает только тогда, когда вы ловите исключение GoogleJsonException, которое вы не получаете, когда у вас есть тайм-аут. Вы можете поймать SocketTimeoutException также в экспоненциальной задержки

У меня был такой же опыт несколько дней назад. Ответ на мой вопрос был найден здесь. https://code.google.com/p/google-api-java-client/wiki/FAQ при создании экземпляра диска можно вызвать метод setHttpRequestInitilalizer, передать новый экземпляр HttpRequestInitializer в качестве аргумента и реализовать метод initialize. Там вы можете увеличить значение ReadTimeout и ConnectionTimeout.

Вот пример кода:

         Drive drive = new Drive.Builder(this.httpTransport, this.jsonFactory, this.credential).setHttpRequestInitializer(new HttpRequestInitializer() {

            @Override
            public void initialize(HttpRequest httpRequest) throws IOException {

                credential.initialize(httpRequest);
                httpRequest.setConnectTimeout(300 * 60000);  // 300 minutes connect timeout
                httpRequest.setReadTimeout(300 * 60000);  // 300 minutes read timeout

            }
        }).setApplicationName("My Application").build();

Экспоненциальный откат-это просто способ дать вам больше шансов повторить его, надеюсь, в следующий раз это будет лучше. Но это не касалось корня проблемы.

Я заметил, что вы установили максимальный результат в 1000. Учитывая, что тайм-аут чтения обычно вызван длительным временем обработки на стороне сервера, я бы предложил вам уменьшить это число до 500 или 200.

Я столкнулся с теми же проблемами, когда выбирал изменения с помощью max result count 1000. Когда я изменю размер на 200 или 500, это работает гладко.

Поскольку допустимое максимальное число связано с ситуацией на сервере и изменяется динамически, можно также разработать стратегию экспоненциального отката для автоматического обновления максимального количества результатов. Например, начните с 1000, если ошибка обнаружена, то измените на 500, если все еще есть ошибка, то измените на 200. Если нет ошибки в течение некоторого времени, то снова увеличьте до 500.

Надеюсь, это поможет~