public V call ( Callable < V > callable ) throws ExecutionException , RetryException { long startTime = System . nanoTime ( ) ; for ( int attemptNumber = 1 ; ; attemptNumber ++ ) { Attempt < V > attempt ; try { V result = attemptTimeLimiter . call ( callable ) ; attempt = new ResultAttempt < V > ( result , attemptNumber , TimeUnit . NANOSECONDS . toMillis ( System . nanoTime ( ) - startTime ) ) ; } catch ( Throwable t ) { attempt = new ExceptionAttempt < V > ( t , attemptNumber , TimeUnit . NANOSECONDS . toMillis ( System . nanoTime ( ) - startTime ) ) ; } for ( RetryListener listener : listeners ) { listener . onRetry ( attempt ) ; } if ( ! rejectionPredicate . apply ( attempt ) ) { return attempt . get ( ) ; } if ( stopStrategy . shouldStop ( attempt ) ) { throw new RetryException ( attemptNumber , attempt ) ; } else { long sleepTime = waitStrategy . computeSleepTime ( attempt ) ; try { blockStrategy . block ( sleepTime ) ; } catch ( InterruptedException e ) { Thread . currentThread ( ) . interrupt ( ) ; throw new RetryException ( attemptNumber , attempt ) ; } } } }
Executes the given callable . If the rejection predicate accepts the attempt the stop strategy is used to decide if a new attempt must be made . Then the wait strategy is used to decide how much time to sleep and a new attempt is made .