private static <T> FlowFuture<T> _exponentialWithJitter(Flows.SerCallable<FlowFuture<T>> op, RetrySettings settings, int attempt) { Flow f = Flows.currentFlow(); try { FlowFuture<T> future = op.call(); return future.exceptionallyCompose((e) -> { if (attempt < settings.maxAttempts) { long delay_max = (long) Math.min( settings.timeUnit.toMillis(settings.delayMaxDuration), settings.timeUnit.toMillis(settings.delayBaseDuration) * Math.pow(2, attempt)); long delay = new Random().longs(1, 0, delay_max).findFirst().getAsLong(); return f.delay(delay, TimeUnit.MILLISECONDS) .thenCompose((a) -> _exponentialWithJitter(op, settings, attempt + 1)); } else { return f.failedFuture(new RuntimeException()); } }); } catch (Exception ex) { return f.failedFuture(new RuntimeException()); } }
private static FlowFuture<BookingRes> cancel(String cancelFn, Object input, Throwable e) { Flows.currentFlow().invokeFunction(cancelFn, input, BookingRes.class); return Flows.currentFlow().failedFuture(e); }
private static FlowFuture<BookingRes> retryCancel(String cancelFn, Object input, Throwable e) { Retry.exponentialWithJitter( () -> Flows.currentFlow().invokeFunction(cancelFn, input, BookingRes.class)); return Flows.currentFlow().failedFuture(e); } }