org.teamapps.ux.task.ProgressCompletableFuture Maven / Gradle / Ivy
/*-
* ========================LICENSE_START=================================
* TeamApps
* ---
* Copyright (C) 2014 - 2024 TeamApps.org
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
package org.teamapps.ux.task;
import org.teamapps.ux.session.CurrentSessionContext;
import org.teamapps.ux.session.SessionContext;
import org.teamapps.ux.task.function.ProgressReportingBiConsumer;
import org.teamapps.ux.task.function.ProgressReportingBiFunction;
import org.teamapps.ux.task.function.ProgressReportingConsumer;
import org.teamapps.ux.task.function.ProgressReportingFunction;
import org.teamapps.ux.task.function.ProgressReportingRunnable;
import org.teamapps.ux.task.function.ProgressReportingSupplier;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class ProgressCompletableFuture extends CompletableFuture {
// basically copy and paste from CompletableFuture...
private static final boolean USE_COMMON_POOL = (ForkJoinPool.getCommonPoolParallelism() > 1);
// basically copy and paste from CompletableFuture...
public static final Executor ASYNC_POOL = USE_COMMON_POOL ? ForkJoinPool.commonPool() : r -> new Thread(r).start();
private final Progress progress;
public ProgressCompletableFuture() {
this(new Progress());
}
public ProgressCompletableFuture(Progress progress) {
this.progress = progress;
}
public ObservableProgress getProgress() {
return progress;
}
public boolean complete(T value) {
progress.markCompleted();
return super.complete(value);
}
public boolean completeExceptionally(Throwable ex) {
progress.markFailed();
return super.completeExceptionally(ex);
}
@Override
public ProgressCompletableFuture newIncompleteFuture() {
return new ProgressCompletableFuture<>();
}
// ========== static =========================
public static ProgressCompletableFuture supplyAsync(ProgressReportingSupplier supplier) {
return supplyAsync(supplier, ASYNC_POOL);
}
public static ProgressCompletableFuture supplyAsync(ProgressReportingSupplier supplier, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
executor.execute(() -> {
future.progress.start();
try {
U result = supplier.get(future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
});
return future;
}
public static ProgressCompletableFuture runAsync(ProgressReportingRunnable runnable) {
return runAsync(runnable, ASYNC_POOL);
}
public static ProgressCompletableFuture runAsync(ProgressReportingRunnable runnable, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
executor.execute(runWrapped(runnable, future));
return future;
}
public static ProgressCompletableFuture supplyAsync(Supplier supplier) {
return supplyAsync(supplier, ASYNC_POOL);
}
public static ProgressCompletableFuture supplyAsync(Supplier supplier, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
executor.execute(() -> {
future.progress.start();
try {
U result = supplier.get();
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
});
return future;
}
public static ProgressCompletableFuture runAsync(Runnable runnable) {
return runAsync(runnable, ASYNC_POOL);
}
public static ProgressCompletableFuture runAsync(Runnable runnable, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
executor.execute(runWrapped(runnable, future));
return future;
}
// ========== with session context ===========
public ProgressCompletableFuture thenApplyWithSessionContext(Function super T, ? extends U> fn) {
SessionContext sessionContext = CurrentSessionContext.get();
return thenApply(t -> {
Object[] result = new Object[1];
sessionContext.runWithContext(() -> result[0] = fn.apply(t));
return (U) result[0];
});
}
public ProgressCompletableFuture thenAcceptWithCurrentSessionContext(Consumer super T> action) {
SessionContext sessionContext = CurrentSessionContext.get();
return thenAccept(t -> sessionContext.runWithContext(() -> action.accept(t)));
}
public ProgressCompletableFuture thenRunWithCurrentSessionContext(Runnable action) {
SessionContext sessionContext = CurrentSessionContext.get();
return thenRun(() -> sessionContext.runWithContext(action));
}
public ProgressCompletableFuture whenCompleteWithCurrentSessionContext(BiConsumer super T, ? super Throwable> action) {
SessionContext sessionContext = CurrentSessionContext.get();
return whenComplete((t, throwable) -> sessionContext.runWithContext(() -> action.accept(t, throwable)));
}
public ProgressCompletableFuture handleWithCurrentSessionContext(BiFunction super T, Throwable, ? extends U> fn) {
SessionContext sessionContext = CurrentSessionContext.get();
return handle((t, throwable) -> {
Object[] result = new Object[1];
sessionContext.runWithContext(() -> result[0] = fn.apply(t, throwable));
return (U) result[0];
});
}
public ProgressCompletableFuture exceptionallyWithCurrentSessionContext(Function fn) {
SessionContext sessionContext = CurrentSessionContext.get();
return exceptionally(throwable -> {
Object[] result = new Object[1];
sessionContext.runWithContext(() -> result[0] = fn.apply(throwable));
return (T) result[0];
});
}
// ========= simple overrides =============
@Override
public ProgressCompletableFuture thenApply(Function super T, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenApply(applyWrapped(fn, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
@Override
public ProgressCompletableFuture thenApplyAsync(Function super T, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenApplyAsync(applyWrapped(fn, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
@Override
public ProgressCompletableFuture thenApplyAsync(Function super T, ? extends U> fn, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenApplyAsync(applyWrapped(fn, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private Function applyWrapped(Function super T, ? extends U> fn, ProgressCompletableFuture future) {
return t -> {
future.progress.start();
try {
U result = fn.apply(t);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
return null;
};
}
@Override
public ProgressCompletableFuture thenAccept(Consumer super T> action) {
ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenAccept(acceptWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
@Override
public ProgressCompletableFuture thenAcceptAsync(Consumer super T> action) {
ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenAcceptAsync(acceptWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
@Override
public ProgressCompletableFuture thenAcceptAsync(Consumer super T> action, Executor executor) {
ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenAcceptAsync(acceptWrapped(action, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private Consumer acceptWrapped(Consumer super T> action, ProgressCompletableFuture future) {
return t -> {
future.progress.start();
try {
action.accept(t);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(null);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
};
}
public ProgressCompletableFuture thenRun(Runnable action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenRun(runWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenRunAsync(Runnable action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenRunAsync(runWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenRunAsync(Runnable action, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenRunAsync(runWrapped(action, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private static Runnable runWrapped(Runnable action, ProgressCompletableFuture future) {
return () -> {
future.progress.start();
try {
action.run();
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(null);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
};
}
public ProgressCompletableFuture whenComplete(BiConsumer super T, ? super Throwable> action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.whenComplete(whenCompleteWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture whenCompleteAsync(BiConsumer super T, ? super Throwable> action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.whenCompleteAsync(whenCompleteWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture whenCompleteAsync(BiConsumer super T, ? super Throwable> action, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.whenCompleteAsync(whenCompleteWrapped(action, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private BiConsumer whenCompleteWrapped(BiConsumer super T, ? super Throwable> action, ProgressCompletableFuture future) {
return (t, throwable) -> {
future.progress.start();
try {
action.accept(t, throwable);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
} catch (Exception e) {
future.progress.markFailed();
} finally {
if (throwable != null) {
future.completeExceptionally(throwable);
} else {
future.complete(t);
}
}
};
}
public ProgressCompletableFuture handle(BiFunction super T, Throwable, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.handle(handleWrapped(fn, future));
return future;
}
public ProgressCompletableFuture handleAsync(BiFunction super T, Throwable, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.handleAsync(handleWrapped(fn, future));
return future;
}
public ProgressCompletableFuture handleAsync(BiFunction super T, Throwable, ? extends U> fn, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.handleAsync(handleWrapped(fn, future), executor);
return future;
}
private BiFunction handleWrapped(BiFunction super T, Throwable, ? extends U> fn, ProgressCompletableFuture future) {
return (t, throwable) -> {
future.progress.start();
try {
U result = fn.apply(t, throwable);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
return null;
};
}
@Override
public ProgressCompletableFuture toCompletableFuture() {
return (ProgressCompletableFuture) super.toCompletableFuture();
}
public ProgressCompletableFuture exceptionally(Function fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.exceptionally(throwable -> {
future.progress.start();
try {
T result = fn.apply(throwable);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
return null;
});
return future;
}
public ProgressCompletableFuture completeAsync(Supplier extends T> supplier, Executor executor) {
return (ProgressCompletableFuture) super.completeAsync(completeWrapped(supplier), executor);
}
public ProgressCompletableFuture completeAsync(Supplier extends T> supplier) {
return (ProgressCompletableFuture) super.completeAsync(completeWrapped(supplier));
}
private Supplier completeWrapped(Supplier extends T> supplier) {
return () -> {
this.progress.start();
try {
T result = supplier.get();
this.progress.markCompleted(); // will get ignored if the progress is already in a final state
this.complete(result);
} catch (Exception e) {
this.progress.markFailed();
this.completeExceptionally(e);
}
return null;
};
}
@Override
public ProgressCompletableFuture orTimeout(long timeout, TimeUnit unit) {
return (ProgressCompletableFuture) super.orTimeout(timeout, unit);
}
@Override
public ProgressCompletableFuture completeOnTimeout(T value, long timeout, TimeUnit unit) {
return (ProgressCompletableFuture) super.completeOnTimeout(value, timeout, unit);
}
// ========== overloaded methods with progress ==================
public ProgressCompletableFuture thenApply(ProgressReportingFunction super T, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenApply(applyWrapped(fn, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenApplyAsync(ProgressReportingFunction super T, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenApplyAsync(applyWrapped(fn, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenApplyAsync(ProgressReportingFunction super T, ? extends U> fn, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenApplyAsync(applyWrapped(fn, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private Function applyWrapped(ProgressReportingFunction super T, ? extends U> fn, ProgressCompletableFuture future) {
return t -> {
future.progress.start();
try {
U result = fn.apply(t, future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
return null;
};
}
public ProgressCompletableFuture thenAccept(ProgressReportingConsumer super T> action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenAccept(acceptWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenAcceptAsync(ProgressReportingConsumer super T> action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenAcceptAsync(acceptWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenAcceptAsync(ProgressReportingConsumer super T> action, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenAcceptAsync(acceptWrapped(action, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private Consumer acceptWrapped(ProgressReportingConsumer super T> action, ProgressCompletableFuture future) {
return t -> {
future.progress.start();
try {
action.accept(t, future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(null);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
};
}
public ProgressCompletableFuture thenRun(ProgressReportingRunnable action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenRun(runWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenRunAsync(ProgressReportingRunnable action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenRunAsync(runWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture thenRunAsync(ProgressReportingRunnable action, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.thenRunAsync(runWrapped(action, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private static Runnable runWrapped(ProgressReportingRunnable action, ProgressCompletableFuture future) {
return () -> {
future.progress.start();
try {
action.run(future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(null);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
};
}
public ProgressCompletableFuture whenComplete(ProgressReportingBiConsumer super T, ? super Throwable> action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.whenComplete(whenCompleteWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture whenCompleteAsync(ProgressReportingBiConsumer super T, ? super Throwable> action) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.whenCompleteAsync(whenCompleteWrapped(action, future))
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
public ProgressCompletableFuture whenCompleteAsync(ProgressReportingBiConsumer super T, ? super Throwable> action, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.whenCompleteAsync(whenCompleteWrapped(action, future), executor)
.exceptionally(throwable -> {
future.completeExceptionally(throwable);
return null;
});
return future;
}
private BiConsumer whenCompleteWrapped(ProgressReportingBiConsumer super T, ? super Throwable> action, ProgressCompletableFuture future) {
return (t, throwable) -> {
future.progress.start();
try {
action.accept(t, throwable, future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
} catch (Exception e) {
future.progress.markFailed();
} finally {
if (throwable != null) {
future.completeExceptionally(throwable);
} else {
future.complete(t);
}
}
};
}
public ProgressCompletableFuture handle(ProgressReportingBiFunction super T, Throwable, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.handle(handleWrapped(fn, future));
return future;
}
public ProgressCompletableFuture handleAsync(ProgressReportingBiFunction super T, Throwable, ? extends U> fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.handleAsync(handleWrapped(fn, future));
return future;
}
public ProgressCompletableFuture handleAsync(ProgressReportingBiFunction super T, Throwable, ? extends U> fn, Executor executor) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.handleAsync(handleWrapped(fn, future), executor);
return future;
}
private BiFunction handleWrapped(ProgressReportingBiFunction super T, Throwable, ? extends U> fn, ProgressCompletableFuture future) {
return (t, throwable) -> {
future.progress.start();
try {
U result = fn.apply(t, throwable, future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
return null;
};
}
public ProgressCompletableFuture exceptionally(ProgressReportingFunction fn) {
final ProgressCompletableFuture future = new ProgressCompletableFuture<>();
super.exceptionally(throwable -> {
future.progress.start();
try {
T result = fn.apply(throwable, future.progress);
future.progress.markCompleted(); // will get ignored if the progress is already in a final state
future.complete(result);
} catch (Exception e) {
future.progress.markFailed();
future.completeExceptionally(e);
}
return null;
});
return future;
}
public ProgressCompletableFuture completeAsync(ProgressReportingSupplier extends T> supplier, Executor executor) {
return (ProgressCompletableFuture) super.completeAsync(completeWrapped(supplier), executor);
}
public ProgressCompletableFuture completeAsync(ProgressReportingSupplier extends T> supplier) {
return (ProgressCompletableFuture) super.completeAsync(completeWrapped(supplier));
}
private Supplier completeWrapped(ProgressReportingSupplier extends T> supplier) {
return () -> {
this.progress.start();
try {
T result = supplier.get(this.progress);
this.progress.markCompleted(); // will get ignored if the progress is already in a final state
this.complete(result);
} catch (Exception e) {
this.progress.markFailed();
this.completeExceptionally(e);
}
return null;
};
}
/* ========== TODO ==============
public ProgressingCompletableFuture thenCombine(CompletionStage extends U> other, BiFunction super T, ? super U, ? extends V> fn)
public ProgressingCompletableFuture thenCombineAsync(CompletionStage extends U> other, BiFunction super T, ? super U, ? extends V> fn)
public ProgressingCompletableFuture thenCombineAsync(CompletionStage extends U> other, BiFunction super T, ? super U, ? extends V> fn, Executor executor)
public ProgressingCompletableFuture thenAcceptBoth(CompletionStage extends U> other, BiConsumer super T, ? super U> action)
public ProgressingCompletableFuture thenAcceptBothAsync(CompletionStage extends U> other, BiConsumer super T, ? super U> action)
public ProgressingCompletableFuture thenAcceptBothAsync(CompletionStage extends U> other, BiConsumer super T, ? super U> action, Executor executor)
public ProgressingCompletableFuture runAfterBoth(CompletionStage> other, Runnable action)
public ProgressingCompletableFuture runAfterBothAsync(CompletionStage> other, Runnable action)
public ProgressingCompletableFuture runAfterBothAsync(CompletionStage> other, Runnable action, Executor executor)
public ProgressingCompletableFuture applyToEither(CompletionStage extends T> other, Function super T, U> fn)
public ProgressingCompletableFuture applyToEitherAsync(CompletionStage extends T> other, Function super T, U> fn)
public ProgressingCompletableFuture applyToEitherAsync(CompletionStage extends T> other, Function super T, U> fn, Executor executor)
public ProgressingCompletableFuture acceptEither(CompletionStage extends T> other, Consumer super T> action)
public ProgressingCompletableFuture acceptEitherAsync(CompletionStage extends T> other, Consumer super T> action)
public ProgressingCompletableFuture acceptEitherAsync(CompletionStage extends T> other, Consumer super T> action, Executor executor)
public ProgressingCompletableFuture runAfterEither(CompletionStage> other, Runnable action)
public ProgressingCompletableFuture runAfterEitherAsync(CompletionStage> other, Runnable action)
public ProgressingCompletableFuture runAfterEitherAsync(CompletionStage> other, Runnable action, Executor executor)
public ProgressingCompletableFuture thenCompose(Function super T, ? extends CompletionStage> fn)
public ProgressingCompletableFuture thenComposeAsync(Function super T, ? extends CompletionStage> fn)
public ProgressingCompletableFuture thenComposeAsync(Function super T, ? extends CompletionStage> fn, Executor executor)
*/
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy