@Override public void onFailure(Call call, IOException exception) { urls.markAsFailed(request().url()); // Fail call if backoffs are exhausted or if no retry URL can be determined. Optional<Duration> backoff = backoffStrategy.nextBackoff(); if (!backoff.isPresent()) { callback.onFailure(call, new IOException("Failed to complete the request due to an " + "IOException", exception)); return; } Optional<HttpUrl> redirectTo = urls.redirectToNext(request().url()); if (!redirectTo.isPresent()) { callback.onFailure(call, new IOException("Failed to determine valid failover URL for '" + request().url() + "' and base URLs " + urls.getBaseUrls())); return; } Request redirectedRequest = request().newBuilder() .url(redirectTo.get()) .build(); RemotingOkHttpCall retryCall = client.newCallWithMutableState(redirectedRequest, backoffStrategy, maxNumRelocations - 1); log.debug("Rescheduling call after backoff", SafeArg.of("backoffMillis", backoff.get().toMillis()), exception); scheduleExecution(() -> retryCall.enqueue(callback), backoff.get()); }
@Override public void onFailure(Call call, IOException exception) { urls.markAsFailed(request().url()); // Fail call if backoffs are exhausted or if no retry URL can be determined. Optional<Duration> backoff = backoffStrategy.nextBackoff(); if (!backoff.isPresent()) { callback.onFailure(call, new IOException("Failed to complete the request due to an " + "IOException", exception)); return; } Optional<HttpUrl> redirectTo = urls.redirectToNext(request().url()); if (!redirectTo.isPresent()) { callback.onFailure(call, new IOException("Failed to determine valid failover URL for '" + request().url() + "' and base URLs " + urls.getBaseUrls())); return; } Request redirectedRequest = request().newBuilder() .url(redirectTo.get()) .build(); RemotingOkHttpCall retryCall = client.newCallWithMutableState(redirectedRequest, backoffStrategy, maxNumRelocations - 1); log.debug("Rescheduling call after backoff", SafeArg.of("backoffMillis", backoff.get().toMillis()), exception); scheduleExecution(() -> retryCall.enqueue(callback), backoff.get()); }
@Override public void run() { for (int i = 0; i < REQUESTS_PER_THREAD; ) { Limiter.Listener listener = Futures.getUnchecked(limiters.acquireLimiterInternal("").acquire()); boolean gotRateLimited = !rateLimiter.tryAcquire(100, TimeUnit.MILLISECONDS); if (!gotRateLimited) { meter.mark(); sleep(successDuration.toMillis()); listener.onSuccess(); avgRetries.update(numRetries); numRetries = 0; backoff = null; i++; } else { initializeBackoff(); Optional<Duration> sleep = backoff.nextBackoff(); numRetries++; if (!sleep.isPresent()) { listener.onIgnore(); throw new RuntimeException("Failed on request " + i); } else { sleep(1); listener.onDropped(); sleep(sleep.get().toMillis()); } } } }