11package io .tarantool .driver .api .retry ;
22
3+ import io .tarantool .driver .core .TarantoolDaemonThreadFactory ;
34import io .tarantool .driver .exceptions .TarantoolAttemptsLimitException ;
45import io .tarantool .driver .exceptions .TarantoolClientException ;
56import io .tarantool .driver .exceptions .TarantoolConnectionException ;
67import io .tarantool .driver .exceptions .TarantoolInternalNetworkException ;
78import io .tarantool .driver .exceptions .TarantoolNoSuchProcedureException ;
8- import io .tarantool .driver .exceptions .TarantoolTimeoutException ;
99import io .tarantool .driver .utils .Assert ;
1010
1111import java .util .concurrent .CompletableFuture ;
1212import java .util .concurrent .CompletionException ;
1313import java .util .concurrent .ExecutionException ;
1414import java .util .concurrent .Executor ;
15+ import java .util .concurrent .Executors ;
16+ import java .util .concurrent .ScheduledExecutorService ;
1517import java .util .concurrent .TimeUnit ;
1618import java .util .concurrent .TimeoutException ;
1719import java .util .function .Predicate ;
@@ -69,6 +71,7 @@ public static final class InfiniteRetryPolicy<T extends Predicate<Throwable>> im
6971 private final long operationTimeout ; //ms
7072 private final long delay ; //ms
7173 private final T exceptionCheck ;
74+ private final ScheduledExecutorService timeoutScheduler ;
7275
7376 /**
7477 * Basic constructor
@@ -89,6 +92,8 @@ public InfiniteRetryPolicy(long requestTimeout, long operationTimeout, long dela
8992 this .operationTimeout = operationTimeout ;
9093 this .delay = delay ;
9194 this .exceptionCheck = exceptionCheck ;
95+ this .timeoutScheduler =
96+ Executors .newSingleThreadScheduledExecutor (new TarantoolDaemonThreadFactory ("tarantool-retry-timeout" ));
9297 }
9398
9499 @ Override
@@ -113,33 +118,20 @@ public long getOperationTimeout() {
113118
114119 @ Override
115120 public <R > CompletableFuture <R > wrapOperation (Supplier <CompletableFuture <R >> operation , Executor executor ) {
116-
117121 Assert .notNull (operation , "Operation must not be null" );
118122 Assert .notNull (executor , "Executor must not be null" );
119123
120- return CompletableFuture .supplyAsync (() -> {
121- long timeElapsed = 0 ;
122- long tStart ;
123- Throwable ex ;
124- do {
125- tStart = System .nanoTime ();
126- try {
127- return operation .get ().get (getRequestTimeout (), TimeUnit .MILLISECONDS );
128- } catch (TimeoutException | InterruptedException e ) {
129- ex = e ;
130- } catch (ExecutionException e ) {
131- ex = e .getCause ();
124+ CompletableFuture <R > resultFuture = new CompletableFuture <>();
125+ CompletableFuture .runAsync (() -> {
126+ doRequest (operation , resultFuture );
127+ timeoutScheduler .schedule (() -> {
128+ if (!resultFuture .isDone ()) {
129+ resultFuture .completeExceptionally (new TimeoutException (String .format (
130+ "Failed to get retrying response within %d ms" , operationTimeout )));
132131 }
133- timeElapsed = timeElapsed + (System .nanoTime () - tStart ) / 1_000_000L ;
134- if (timeElapsed >= getOperationTimeout ()) {
135- ex = new TarantoolTimeoutException (
136- timeElapsed ,
137- ex );
138- break ;
139- }
140- } while (this .canRetryRequest (ex ));
141- throw new CompletionException (ex );
132+ }, operationTimeout , TimeUnit .MILLISECONDS );
142133 }, executor );
134+ return resultFuture ;
143135 }
144136 }
145137
0 commit comments