Details
-
Bug
-
Status: Resolved
-
Normal
-
Resolution: Fixed
-
None
-
Correctness - API / Semantic Implementation
-
Normal
-
Low Hanging Fruit
-
Code Inspection
-
All
-
None
-
Description
public static Deadline retryIndefinitely(long timeoutNanos, Meter retryMeter) { return new Deadline(Clock.Global.nanoTime() + timeoutNanos, new Retry.Jitter(Integer.MAX_VALUE, DEFAULT_BACKOFF_MS, new Random(), retryMeter)) { @Override public boolean reachedMax() { return false; } @Override public long remainingNanos() { return timeoutNanos; } public String toString() { return String.format("RetryIndefinitely{tries=%d}", currentTries()); } }; }
Sample usage pattern (example is in Accord, but same pattern exists in RemoteProcessor.commit)
Promise<LogState> request = new AsyncPromise<>(); List<InetAddressAndPort> candidates = new ArrayList<>(log.metadata().fullCMSMembers()); sendWithCallbackAsync(request, Verb.TCM_RECONSTRUCT_EPOCH_REQ, new ReconstructLogState(lowEpoch, highEpoch, includeSnapshot), new CandidateIterator(candidates), retryPolicy); return request.get(retryPolicy.remainingNanos(), TimeUnit.NANOSECONDS);
The issue here is that the networking retry has no clue that we gave up waiting on the request, so we will keep retrying until success! The reason for this is “reachedMax” is used to see if its safe to run again, but it isn’t as the deadline has passed!