net.tascalate.concurrent.DependentPromise Maven / Gradle / Ivy
Show all versions of net.tascalate.concurrent Show documentation
/**
* Copyright 2015-2019 Valery Silaev (http://vsilaev.com)
*
* 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.
*/
package net.tascalate.concurrent;
import java.time.Duration;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
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;
import net.tascalate.concurrent.decorators.ExecutorBoundDependentPromise;
/**
*
* {@link Promise} wrapper that may keep track origin of this promise and cancel them
* along with this promise itself.
*
* For example:
*
*
* DependentPromise<?> p1 = DependentPromise.from(CallableTask.runAsync(this::someLongRunningMethod, myExecutor));
* DependentPromise<?> p2 = p1.thenRunAsync(this::someOtherLongRunningTask, true);
* ...
* p2.cancel(true);
*
*
*
* In the example p2
is created with specifying p1
as origin (last argument is true
).
* Now when canceling p2
both p2
and p1
will be cancelled if not completed yet.
*
*
The class add overloads to all composition methods declared in {@link CompletionStage} interface.
*
*
The ones that accepts another {@link CompletionStage} as argument (named *Both*
and
* *Either*
are overloaded with a set of @{link {@link PromiseOrigin} as an argument to let
* you specify what to enlist as origin: "this" related to method call or the parameter.
*
*
Rest of methods from {@link CompletionStage} API are overloaded with boolean argument
* enlistOrigin
that specify whether or not the {@link Promise} object whose
* method is invoiked should be added as an origin to result.
*
*
All methods originally specified in {@link CompletionStage} does not add "this" as an origin to
* resulting promise.
*
* @author vsilaev
*
* @param
* a type of the successfully resolved promise value
*/
public interface DependentPromise extends Promise {
// Only for backward-compatibility with versions below 0.5.4
public static DependentPromise from(Promise source) {
return ConfigurableDependentPromise.from(source);
}
// For symmetry with above
public static DependentPromise from(Promise source, Set defaultEnlistOptions) {
return ConfigurableDependentPromise.from(source, defaultEnlistOptions);
}
@Override
default DependentPromise defaultAsyncOn(Executor executor) {
return new ExecutorBoundDependentPromise<>(this, executor);
}
// Delay
@Override
default DependentPromise delay(long timeout, TimeUnit unit) {
return delay(timeout, unit, true);
}
@Override
default DependentPromise delay(long timeout, TimeUnit unit, boolean delayOnError) {
return delay(Timeouts.toDuration(timeout, unit), delayOnError);
}
@Override
default DependentPromise delay(Duration duration) {
return delay(duration, true);
}
default DependentPromise delay(long timeout, TimeUnit unit, boolean delayOnError, boolean enlistOrigin) {
return delay(Timeouts.toDuration(timeout, unit), delayOnError, enlistOrigin);
}
@Override
DependentPromise delay(Duration duration, boolean delayOnError);
DependentPromise delay(Duration duration, boolean delayOnError, boolean enlistOrigin);
// Or Timeout
@Override
default DependentPromise orTimeout(long timeout, TimeUnit unit) {
return orTimeout(timeout, unit, true);
}
@Override
default DependentPromise orTimeout(long timeout, TimeUnit unit, boolean cancelOnTimeout) {
return orTimeout(Timeouts.toDuration(timeout, unit), cancelOnTimeout);
}
default DependentPromise orTimeout(long timeout, TimeUnit unit, boolean cancelOnTimeout, boolean enlistOrigin) {
return orTimeout(Timeouts.toDuration(timeout, unit), cancelOnTimeout, enlistOrigin);
}
@Override
default DependentPromise orTimeout(Duration duration) {
return orTimeout(duration, true);
}
@Override
DependentPromise orTimeout(Duration duration, boolean cancelOnTimeout);
DependentPromise orTimeout(Duration duration, boolean cancelOnTimeout, boolean enlistOrigin);
// On Timeout
@Override
default DependentPromise onTimeout(T value, long timeout, TimeUnit unit) {
return onTimeout(value, timeout, unit, true);
}
@Override
default DependentPromise onTimeout(T value, long timeout, TimeUnit unit, boolean cancelOnTimeout) {
return onTimeout(value, Timeouts.toDuration(timeout, unit), cancelOnTimeout);
}
default DependentPromise onTimeout(T value, long timeout, TimeUnit unit, boolean cancelOnTimeout, boolean enlistOrigin) {
return onTimeout(value, Timeouts.toDuration(timeout, unit), cancelOnTimeout, enlistOrigin);
}
@Override
default DependentPromise onTimeout(T value, Duration duration) {
return onTimeout(value, duration, true);
}
@Override
DependentPromise onTimeout(T value, Duration duration, boolean cancelOnTimeout);
DependentPromise onTimeout(T value, Duration duration, boolean cancelOnTimeout, boolean enlistOrigin);
@Override
default DependentPromise onTimeout(Supplier extends T> supplier, long timeout, TimeUnit unit) {
return onTimeout(supplier, timeout, unit, true);
}
@Override
default DependentPromise onTimeout(Supplier extends T> supplier, long timeout, TimeUnit unit, boolean cancelOnTimeout) {
return onTimeout(supplier, Timeouts.toDuration(timeout, unit), cancelOnTimeout);
}
default DependentPromise onTimeout(Supplier extends T> supplier, long timeout, TimeUnit unit, boolean cancelOnTimeout, boolean enlistOrigin) {
return onTimeout(supplier, Timeouts.toDuration(timeout, unit), cancelOnTimeout, enlistOrigin);
}
@Override
default DependentPromise onTimeout(Supplier extends T> supplier, Duration duration) {
return onTimeout(supplier, duration, true);
}
@Override
DependentPromise onTimeout(Supplier extends T> supplier, Duration duration, boolean cancelOnTimeout);
DependentPromise onTimeout(Supplier extends T> supplier, Duration duration, boolean cancelOnTimeout, boolean enlistOrigin);
DependentPromise thenApply(Function super T, ? extends U> fn, boolean enlistOrigin);
DependentPromise thenApplyAsync(Function super T, ? extends U> fn, boolean enlistOrigin);
DependentPromise thenApplyAsync(Function super T, ? extends U> fn, Executor executor, boolean enlistOrigin);
DependentPromise thenAccept(Consumer super T> action, boolean enlistOrigin);
DependentPromise thenAcceptAsync(Consumer super T> action, boolean enlistOrigin);
DependentPromise thenAcceptAsync(Consumer super T> action, Executor executor, boolean enlistOrigin);
DependentPromise thenRun(Runnable action, boolean enlistOrigin);
DependentPromise thenRunAsync(Runnable action, boolean enlistOrigin);
DependentPromise thenRunAsync(Runnable action, Executor executor, boolean enlistOrigin);
DependentPromise thenCombine(CompletionStage extends U> other,
BiFunction super T, ? super U, ? extends V> fn,
Set enlistOptions);
DependentPromise thenCombineAsync(CompletionStage extends U> other,
BiFunction super T, ? super U, ? extends V> fn,
Set enlistOptions);
DependentPromise thenCombineAsync(CompletionStage extends U> other,
BiFunction super T, ? super U, ? extends V> fn,
Executor executor,
Set enlistOptions);
DependentPromise thenAcceptBoth(CompletionStage extends U> other,
BiConsumer super T, ? super U> action,
Set enlistOptions);
DependentPromise thenAcceptBothAsync(CompletionStage extends U> other,
BiConsumer super T, ? super U> action,
Set enlistOptions);
DependentPromise thenAcceptBothAsync(CompletionStage extends U> other,
BiConsumer super T, ? super U> action,
Executor executor,
Set enlistOptions);
DependentPromise runAfterBoth(CompletionStage> other, Runnable action, Set enlistOptions);
DependentPromise runAfterBothAsync(CompletionStage> other, Runnable action, Set enlistOptions);
DependentPromise runAfterBothAsync(CompletionStage> other,
Runnable action,
Executor executor,
Set enlistOptions);
DependentPromise applyToEither(CompletionStage extends T> other,
Function super T, U> fn,
Set enlistOptions);
DependentPromise applyToEitherAsync(CompletionStage extends T> other,
Function super T, U> fn,
Set enlistOptions);
DependentPromise applyToEitherAsync(CompletionStage extends T> other,
Function super T, U> fn,
Executor executor,
Set enlistOptions);
DependentPromise acceptEither(CompletionStage extends T> other,
Consumer super T> action,
Set enlistOptions);
DependentPromise acceptEitherAsync(CompletionStage extends T> other,
Consumer super T> action,
Set enlistOptions);
DependentPromise acceptEitherAsync(CompletionStage extends T> other,
Consumer super T> action,
Executor executor,
Set enlistOptions);
DependentPromise runAfterEither(CompletionStage> other, Runnable action, Set enlistOptions);
DependentPromise runAfterEitherAsync(CompletionStage> other, Runnable action, Set enlistOptions);
DependentPromise runAfterEitherAsync(CompletionStage> other,
Runnable action,
Executor executor,
Set enlistOptions);
DependentPromise thenCompose(Function super T, ? extends CompletionStage> fn, boolean enlistOrigin);
DependentPromise thenComposeAsync(Function super T, ? extends CompletionStage> fn, boolean enlistOrigin);
DependentPromise thenComposeAsync(Function super T, ? extends CompletionStage> fn, Executor executor, boolean enlistOrigin);
DependentPromise exceptionally(Function fn, boolean enlistOrigin);
DependentPromise whenComplete(BiConsumer super T, ? super Throwable> action, boolean enlistOrigin);
DependentPromise whenCompleteAsync(BiConsumer super T, ? super Throwable> action, boolean enlistOrigin);
DependentPromise whenCompleteAsync(BiConsumer super T, ? super Throwable> action, Executor executor, boolean enlistOrigin);
DependentPromise handle(BiFunction super T, Throwable, ? extends U> fn, boolean enlistOrigin);
DependentPromise handleAsync(BiFunction super T, Throwable, ? extends U> fn, boolean enlistOrigin);
DependentPromise handleAsync(BiFunction super T, Throwable, ? extends U> fn, Executor executor, boolean enlistOrigin);
CompletableFuture toCompletableFuture(boolean enlistOrigin);
// Re-declare CompletionStage original methods with right return type
@Override
DependentPromise thenApply(Function super T, ? extends U> fn);
@Override
DependentPromise thenApplyAsync(Function super T, ? extends U> fn);
@Override
DependentPromise thenApplyAsync(Function super T, ? extends U> fn, Executor executor);
@Override
DependentPromise thenAccept(Consumer super T> action);
@Override
DependentPromise thenAcceptAsync(Consumer super T> action);
@Override
DependentPromise thenAcceptAsync(Consumer super T> action, Executor executor);
@Override
DependentPromise thenRun(Runnable action);
@Override
DependentPromise thenRunAsync(Runnable action);
@Override
DependentPromise thenRunAsync(Runnable action, Executor executor);
@Override
DependentPromise thenCombine(CompletionStage extends U> other, BiFunction super T, ? super U, ? extends V> fn);
@Override
DependentPromise thenCombineAsync(CompletionStage extends U> other, BiFunction super T, ? super U, ? extends V> fn);
@Override
DependentPromise thenCombineAsync(CompletionStage extends U> other,
BiFunction super T, ? super U, ? extends V> fn,
Executor executor);
@Override
DependentPromise thenAcceptBoth(CompletionStage extends U> other, BiConsumer super T, ? super U> action);
@Override
DependentPromise thenAcceptBothAsync(CompletionStage extends U> other, BiConsumer super T, ? super U> action);
@Override
DependentPromise thenAcceptBothAsync(CompletionStage extends U> other,
BiConsumer super T, ? super U> action,
Executor executor);
@Override
DependentPromise runAfterBoth(CompletionStage> other, Runnable action);
@Override
DependentPromise runAfterBothAsync(CompletionStage> other, Runnable action);
@Override
DependentPromise runAfterBothAsync(CompletionStage> other,
Runnable action,
Executor executor);
@Override
DependentPromise applyToEither(CompletionStage extends T> other, Function super T, U> fn);
@Override
DependentPromise applyToEitherAsync(CompletionStage extends T> other, Function super T, U> fn);
@Override
DependentPromise applyToEitherAsync(CompletionStage extends T> other,
Function super T, U> fn,
Executor executor);
@Override
DependentPromise acceptEither(CompletionStage extends T> other, Consumer super T> action);
@Override
DependentPromise acceptEitherAsync(CompletionStage extends T> other, Consumer super T> action);
@Override
DependentPromise acceptEitherAsync(CompletionStage extends T> other,
Consumer super T> action,
Executor executor);
@Override
DependentPromise runAfterEither(CompletionStage> other, Runnable action);
@Override
DependentPromise runAfterEitherAsync(CompletionStage> other, Runnable action);
@Override
DependentPromise runAfterEitherAsync(CompletionStage> other,
Runnable action,
Executor executor);
@Override
DependentPromise thenCompose(Function super T, ? extends CompletionStage> fn);
@Override
DependentPromise thenComposeAsync(Function super T, ? extends CompletionStage> fn);
@Override
DependentPromise thenComposeAsync(Function super T, ? extends CompletionStage> fn, Executor executor);
@Override
DependentPromise exceptionally(Function fn);
@Override
DependentPromise whenComplete(BiConsumer super T, ? super Throwable> action);
@Override
DependentPromise whenCompleteAsync(BiConsumer super T, ? super Throwable> action);
@Override
DependentPromise whenCompleteAsync(BiConsumer super T, ? super Throwable> action, Executor executor);
@Override
DependentPromise handle(BiFunction super T, Throwable, ? extends U> fn);
@Override
DependentPromise handleAsync(BiFunction super T, Throwable, ? extends U> fn);
@Override
DependentPromise handleAsync(BiFunction super T, Throwable, ? extends U> fn, Executor executor);
}