dcapwell commented on code in PR #3379:
URL: https://github.com/apache/cassandra/pull/3379#discussion_r1645033471


##########
src/java/org/apache/cassandra/service/accord/AccordService.java:
##########
@@ -430,57 +442,76 @@ public long repair(@Nonnull Seekables keysOrRanges, long 
epoch, long queryStartN
         return barrier(keysOrRanges, epoch, queryStartNanos, timeoutNanos, 
barrierType, isForWrite, repairSyncPoint(allNodes));
     }
 
-    private static ReadTimeoutException newBarrierTimeout(TxnId txnId, boolean 
global)
+    @VisibleForTesting
+    static ReadTimeoutException newBarrierTimeout(TxnId txnId, boolean global)
     {
         return new ReadTimeoutException(global ? ConsistencyLevel.ANY : 
ConsistencyLevel.QUORUM, 0, 0, false, txnId.toString());
     }
 
-    private static ReadTimeoutException newBarrierPreempted(TxnId txnId, 
boolean global)
+    @VisibleForTesting
+    static ReadTimeoutException newBarrierPreempted(TxnId txnId, boolean 
global)
     {
         return new ReadPreemptedException(global ? ConsistencyLevel.ANY : 
ConsistencyLevel.QUORUM, 0, 0, false, txnId.toString());
     }
 
-    private long doWithRetries(LongSupplier action, int retryAttempts, long 
initialBackoffMillis, long maxBackoffMillis) throws InterruptedException
+    @VisibleForTesting
+    static ReadExhaustedException newBarrierExhausted(TxnId txnId, boolean 
global)
+    {
+        //TODO (usability): not being able to show the txn is a bad UX, this 
becomes harder to trace back in logs
+        return new ReadExhaustedException(global ? ConsistencyLevel.ANY : 
ConsistencyLevel.QUORUM, 0, 0, false, ImmutableMap.of());
+    }
+
+    @VisibleForTesting
+    static boolean isTimeout(Throwable t)
+    {
+        return t instanceof Timeout || t instanceof ReadTimeoutException || t 
instanceof Preempted || t instanceof ReadPreemptedException;
+    }
+
+    @VisibleForTesting
+    static long doWithRetries(Blocking blocking, LongSupplier action, int 
retryAttempts, long initialBackoffMillis, long maxBackoffMillis) throws 
InterruptedException
     {
         // Since we could end up having the barrier transaction or the 
transaction it listens to invalidated
-        RuntimeException existingFailures = null;
+        Throwable existingFailures = null;
         Long success = null;
-        long backoffMillis = 0;
+        long backoffMillis = initialBackoffMillis;
         for (int attempt = 0; attempt < retryAttempts; attempt++)
         {
-            try
-            {
-                Thread.sleep(backoffMillis);
-            }
-            catch (InterruptedException e)
-            {
-                if (existingFailures != null)
-                    e.addSuppressed(existingFailures);
-                throw e;
-            }
-            backoffMillis = backoffMillis == 0 ? initialBackoffMillis : 
Math.min(backoffMillis * 2, maxBackoffMillis);
             try
             {
                 success = action.getAsLong();
                 break;
             }
             catch (RequestExecutionException | CoordinationFailed newFailures)
             {
-                existingFailures = Throwables.merge(existingFailures, 
newFailures);
+                existingFailures = FailureAccumulator.append(existingFailures, 
newFailures, AccordService::isTimeout);
+
+                try
+                {
+                    blocking.sleep(backoffMillis);
+                }
+                catch (InterruptedException e)
+                {
+                    if (existingFailures != null)
+                        e.addSuppressed(existingFailures);
+                    throw e;
+                }
+                backoffMillis = Math.min(backoffMillis * 2, maxBackoffMillis);
             }
+            // if an unknown/unexpected error happens retry stops right away
         }
         if (success == null)
         {
             checkState(existingFailures != null, "Didn't have success, but 
also didn't have failures");
-            throw existingFailures;
+            Throwables.throwIfUnchecked(existingFailures);
+            throw new RuntimeException(existingFailures);

Review Comment:
   this is possible on the JVM, but super tacky to hit this case... you either 
do this *outside* of javac or trick javac... In the common case (most likely 
100%) we will return from the previous line



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to