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); } }
public static void sendSuccessMail(BookingRes flightRes, BookingRes hotelRes, BookingRes carRes) { EmailReq message = composeSuccessEmail(flightRes, hotelRes, carRes); Flows.currentFlow().invokeFunction("./email", message); } }
@Override public Object toJava(boolean successful, FlowId flowId, BlobStoreClient blobStore, ClassLoader classLoader) { return ((RemoteFlow) Flows.currentFlow()).createFlowFuture(new CompletionId(stageId)); } }
public static void sendFailEmail() { Flows.currentFlow().invokeFunction("./email", composeFailEmail()); }
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()); } }
public void book1(TripReq input) { Flow f = Flows.currentFlow(); FlowFuture<BookingRes> flightFuture = f.invokeFunction("./flight/book", input.flight, BookingRes.class); FlowFuture<BookingRes> hotelFuture = f.invokeFunction("./hotel/book", input.hotel, BookingRes.class); FlowFuture<BookingRes> carFuture = f.invokeFunction("./car/book", input.carRental, BookingRes.class); flightFuture.thenCompose( (flightRes) -> hotelFuture.thenCompose( (hotelRes) -> carFuture.whenComplete( (carRes, e) -> EmailReq.sendSuccessMail(flightRes, hotelRes, carRes) ) ) ); }
public Response handleRequest(byte[] imageBuffer) { String id = java.util.UUID.randomUUID().toString(); Flow runtime = Flows.currentFlow(); runtime.allOf( runtime.invokeFunction(resize128ID, HttpMethod.POST, Headers.emptyHeaders(), imageBuffer) .thenAccept((img) -> objectUpload(img.getBodyAsBytes(), id + "-128.png")), runtime.invokeFunction(resize256ID, HttpMethod.POST, Headers.emptyHeaders(), imageBuffer) .thenAccept((img) -> objectUpload(img.getBodyAsBytes(), id + "-256.png")), runtime.invokeFunction(resize512ID, HttpMethod.POST, Headers.emptyHeaders(), imageBuffer) .thenAccept((img) -> objectUpload(img.getBodyAsBytes(), id + "-512.png")), runtime.supply(() -> objectUpload(imageBuffer, id + ".png")) ); return new Response(id); }
public void book3(TripReq input) { Flow f = Flows.currentFlow(); FlowFuture<BookingRes> flightFuture = f.invokeFunction("./flight/book", input.flight, BookingRes.class); FlowFuture<BookingRes> hotelFuture = f.invokeFunction("./hotel/book", input.hotel, BookingRes.class); FlowFuture<BookingRes> carFuture = f.invokeFunction("./car/book", input.carRental, BookingRes.class); flightFuture.thenCompose( (flightRes) -> hotelFuture.thenCompose( (hotelRes) -> carFuture.whenComplete( (carRes, e) -> EmailReq.sendSuccessMail(flightRes, hotelRes, carRes) ) .exceptionallyCompose( (e) -> retryCancel("./car/cancel", input.carRental, e) ) ) .exceptionallyCompose( (e) -> retryCancel("./hotel/cancel", input.hotel, e) ) ) .exceptionallyCompose( (e) -> retryCancel("./flight/cancel", input.flight, e) ) .exceptionally( (err) -> {EmailReq.sendFailEmail(); return null;} ); }
public void book2(TripReq input) { Flow f = Flows.currentFlow(); FlowFuture<BookingRes> flightFuture = f.invokeFunction("./flight/book", input.flight, BookingRes.class); FlowFuture<BookingRes> hotelFuture = f.invokeFunction("./hotel/book", input.hotel, BookingRes.class); FlowFuture<BookingRes> carFuture = f.invokeFunction("./car/book", input.carRental, BookingRes.class); flightFuture.thenCompose( (flightRes) -> hotelFuture.thenCompose( (hotelRes) -> carFuture.whenComplete( (carRes, e) -> EmailReq.sendSuccessMail(flightRes, hotelRes, carRes) ) .exceptionallyCompose( (e) -> cancel("./car/cancel", input.carRental, e) ) ) .exceptionallyCompose( (e) -> cancel("./hotel/cancel", input.hotel, e) ) ) .exceptionallyCompose( (e) -> cancel("./flight/cancel", input.flight, e) ) .exceptionally( (err) -> {EmailReq.sendFailEmail(); return null;} ); }