/** * Equivalent to {@code withRetryPolicy("operation", policy, taskSupplier)}. * @see #withRetryPolicy(String, RetryPolicy, Callable) */ public static <T> Task<T> withRetryPolicy(RetryPolicy policy, Callable<Task<T>> taskSupplier) { return withRetryPolicy("operation", policy, taskSupplier); }
/** * Equivalent to {@code withRetryPolicy("operation", policy, taskSupplier)}. * @see #withRetryPolicy(String, RetryPolicy, Callable) */ public static <T> Task<T> withRetryPolicy(RetryPolicy policy, Function1<Integer, Task<T>> taskSupplier) { return withRetryPolicy("operation", policy, taskSupplier); }
/** * Creates a new task that will run and potentially retry task returned * by a {@code taskSupplier}. Use {@link RetryPolicyBuilder} to create desired * retry policy. * <p> * NOTE: using tasks with retry can have significant performance implications. For example, HTTP request may * failed due to server overload and retrying request may prevent server from recovering. In this example * a better approach is the opposite: decrease number of requests to the server unit it is fully recovered. * Please make sure you have considered why the first task failed and why is it reasonable to expect retry task * to complete successfully. It is also highly recommended to specify reasonable backoff and termination conditions. * * @param name A name of the task that needs to be retried. * @param policy Retry policy that will control this task's retry behavior. * @param taskSupplier A task generator function. * @param <T> the type of the return value for this task */ public static <T> Task<T> withRetryPolicy(String name, RetryPolicy policy, Callable<Task<T>> taskSupplier) { return withRetryPolicy(name, policy, attempt -> taskSupplier.call()); }
@Test public void testFailingTaskSupplier() { Task<Void> task = withRetryPolicy("testFailingTaskSupplier", RetryPolicy.attempts(3, 0), attempt -> { throw new IOException("ups"); }); runAndWaitException(task, IOException.class); assertTrue(task.isDone()); }
@Test public void testSimpleRetryPolicy() { Task<Void> task = withRetryPolicy("testSimpleRetryPolicy", RetryPolicy.attempts(3, 0), attempt -> Task.failure(new RuntimeException("current attempt: " + attempt))); runAndWaitException(task, RuntimeException.class); assertTrue(task.isDone()); assertEquals(task.getError().getMessage(), "current attempt: 2"); }
@Test public void testSimpleRetryPolicy() { Task<Void> task = withRetryPolicy("testSimpleRetryPolicy", RetryPolicy.attempts(3, 0), attempt -> Task.failure(new RuntimeException("current attempt: " + attempt))); runAndWaitException(task, RuntimeException.class); assertTrue(task.isDone()); assertEquals(task.getError().getMessage(), "current attempt: 2"); }
@Test public void testSuccessfulTask() { Task<String> task = withRetryPolicy(RetryPolicy.attempts(3, 0), attempt -> Task.value("successful attempt " + attempt)); runAndWait(task); assertTrue(task.isDone()); assertEquals(task.get(), "successful attempt 0"); }
@Test public void testSuccessfulTask() { Task<String> task = withRetryPolicy(RetryPolicy.attempts(3, 0), attempt -> Task.value("successful attempt " + attempt)); runAndWait(task); assertTrue(task.isDone()); assertEquals(task.get(), "successful attempt 0"); }
@Test public void testErrorClassification() { Function<Throwable, ErrorClassification> errorClassifier = error -> error instanceof TimeoutException ? ErrorClassification.RECOVERABLE : ErrorClassification.UNRECOVERABLE; RetryPolicy retryPolicy = new RetryPolicyBuilder(). setTerminationPolicy(TerminationPolicy.limitAttempts(3)). setErrorClassifier(errorClassifier). build(); assertEquals(retryPolicy.getName(), "RetryPolicy.LimitAttempts"); Task<Void> task1 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new TimeoutException("current attempt: " + attempt))); runAndWaitException(task1, TimeoutException.class); assertTrue(task1.isDone()); assertEquals(task1.getError().getMessage(), "current attempt: 2"); Task<Void> task2 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new IllegalArgumentException("current attempt: " + attempt))); runAndWaitException(task2, IllegalArgumentException.class); assertTrue(task2.isDone()); assertEquals(task2.getError().getMessage(), "current attempt: 0"); } }
@Test public void testErrorClassification() { Function<Throwable, ErrorClassification> errorClassifier = error -> error instanceof TimeoutException ? ErrorClassification.RECOVERABLE : ErrorClassification.UNRECOVERABLE; RetryPolicy retryPolicy = new RetryPolicyBuilder(). setTerminationPolicy(TerminationPolicy.limitAttempts(3)). setErrorClassifier(errorClassifier). build(); assertEquals(retryPolicy.getName(), "RetryPolicy.LimitAttempts"); Task<Void> task1 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new TimeoutException("current attempt: " + attempt))); runAndWaitException(task1, TimeoutException.class); assertTrue(task1.isDone()); assertEquals(task1.getError().getMessage(), "current attempt: 2"); Task<Void> task2 = withRetryPolicy("testErrorClassification", retryPolicy, attempt -> Task.failure(new IllegalArgumentException("current attempt: " + attempt))); runAndWaitException(task2, IllegalArgumentException.class); assertTrue(task2.isDone()); assertEquals(task2.getError().getMessage(), "current attempt: 0"); }
@Test public void testWithRetryTaskType() { Task<String> task = Task.withRetryPolicy(RetryPolicy.attempts(1, 0), attempt -> Task.value("successful attempt " + attempt)); runAndWait(task); assertEquals(doesTaskTypeExistInTrace(task.getTrace(), TaskType.RETRY.getName()), true); assertEquals(task.getShallowTrace().getTaskType(), TaskType.WITH_RETRY.getName()); }
/** * Equivalent to {@code withRetryPolicy("operation", policy, taskSupplier)}. * @see #withRetryPolicy(String, RetryPolicy, Callable) */ public static <T> Task<T> withRetryPolicy(RetryPolicy policy, Function1<Integer, Task<T>> taskSupplier) { return withRetryPolicy("operation", policy, taskSupplier); }
/** * Equivalent to {@code withRetryPolicy("operation", policy, taskSupplier)}. * @see #withRetryPolicy(String, RetryPolicy, Callable) */ public static <T> Task<T> withRetryPolicy(RetryPolicy policy, Callable<Task<T>> taskSupplier) { return withRetryPolicy("operation", policy, taskSupplier); }
/** * Creates a new task that will run and potentially retry task returned * by a {@code taskSupplier}. Use {@link RetryPolicyBuilder} to create desired * retry policy. * <p> * NOTE: using tasks with retry can have significant performance implications. For example, HTTP request may * failed due to server overload and retrying request may prevent server from recovering. In this example * a better approach is the opposite: decrease number of requests to the server unit it is fully recovered. * Please make sure you have considered why the first task failed and why is it reasonable to expect retry task * to complete successfully. It is also highly recommended to specify reasonable backoff and termination conditions. * * @param name A name of the task that needs to be retried. * @param policy Retry policy that will control this task's retry behavior. * @param taskSupplier A task generator function. * @param <T> the type of the return value for this task */ public static <T> Task<T> withRetryPolicy(String name, RetryPolicy policy, Callable<Task<T>> taskSupplier) { return withRetryPolicy(name, policy, attempt -> taskSupplier.call()); }