public abstract class AbstractFuture<V> extends java.lang.Object implements Future<V>
Future
implementation, with all state being managed without locks (except those used by the JVM).
Some implementation comments versus Netty's default promise:
- We permit efficient initial state declaration, avoiding unnecessary CAS or lock acquisitions when mutating
a Promise we are ourselves constructing (and can easily add more; only those we use have been added)
- We guarantee the order of invocation of listeners (and callbacks etc, and with respect to each other)
- We save some space when registering listeners, especially if there is only one listener, as we perform no
extra allocations in this case.
- We implement our invocation list as a concurrent stack, that is cleared on notification
- We handle special values slightly differently.
- We do not use a special value for null, instead using a special value to indicate the result has not been set.
This means that once isSuccess() holds, the result must be a correctly typed object (modulo generics pitfalls).
- All special values are also instances of FailureHolder, which simplifies a number of the logical conditions.Awaitable.AbstractAwaitable, Awaitable.AsyncAwaitable, Awaitable.Defaults, Awaitable.SyncAwaitable
Modifier and Type | Field and Description |
---|---|
protected static org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder |
CANCELLED |
protected static org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder |
UNCANCELLABLE |
protected static org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder |
UNSET |
Modifier | Constructor and Description |
---|---|
|
AbstractFuture() |
protected |
AbstractFuture(org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder initialState) |
protected |
AbstractFuture(org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder initialState,
io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener) |
protected |
AbstractFuture(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener) |
protected |
AbstractFuture(java.lang.Throwable immediateFailure) |
protected |
AbstractFuture(V immediateSuccess) |
Modifier and Type | Method and Description |
---|---|
AbstractFuture<V> |
addCallback(java.util.function.BiConsumer<? super V,java.lang.Throwable> callback)
Support
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor) natively
See addListener(GenericFutureListener) for ordering semantics. |
Future<V> |
addCallback(java.util.function.BiConsumer<? super V,java.lang.Throwable> callback,
java.util.concurrent.Executor executor)
Support
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor) natively |
AbstractFuture<V> |
addCallback(java.util.function.Consumer<? super V> onSuccess,
java.util.function.Consumer<? super java.lang.Throwable> onFailure)
Support more fluid version of
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
See addListener(GenericFutureListener) for ordering semantics. |
AbstractFuture<V> |
addCallback(java.util.function.Consumer<? super V> onSuccess,
java.util.function.Consumer<? super java.lang.Throwable> onFailure,
java.util.concurrent.Executor executor)
Support more fluid version of
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
See addListener(GenericFutureListener) for ordering semantics. |
AbstractFuture<V> |
addCallback(com.google.common.util.concurrent.FutureCallback<? super V> callback)
Support
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor) natively
See addListener(GenericFutureListener) for ordering semantics. |
AbstractFuture<V> |
addCallback(com.google.common.util.concurrent.FutureCallback<? super V> callback,
java.util.concurrent.Executor executor)
Support
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor) natively
See addListener(GenericFutureListener) for ordering semantics. |
Future<V> |
addListener(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener)
Add a listener to be invoked once this future completes.
|
void |
addListener(java.lang.Runnable task)
Add a listener to be invoked once this future completes.
|
void |
addListener(java.lang.Runnable task,
java.util.concurrent.Executor executor)
Add a listener to be invoked once this future completes.
|
Future<V> |
addListeners(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>>... listeners) |
boolean |
await(long timeout,
java.util.concurrent.TimeUnit unit)
Await for the specified period, throwing any interrupt.
|
Future<V> |
awaitThrowUncheckedOnInterrupt()
Wait for this future to complete
Awaitable.awaitThrowUncheckedOnInterrupt() |
boolean |
awaitThrowUncheckedOnInterrupt(long time,
java.util.concurrent.TimeUnit units)
Await for the specified period, throwing any interrupt as an unchecked exception.
|
Future<V> |
awaitUninterruptibly()
Wait for this future to complete
Awaitable.awaitUninterruptibly() |
boolean |
awaitUninterruptibly(long timeout,
java.util.concurrent.TimeUnit unit)
Await until the deadline (in nanoTime), ignoring interrupts (but maintaining the interrupt flag on exit).
|
boolean |
awaitUntilThrowUncheckedOnInterrupt(long nanoTimeDeadline)
Await until the deadline (in nanoTime), throwing any interrupt as an unchecked exception.
|
boolean |
awaitUntilUninterruptibly(long nanoTimeDeadline)
Await until the deadline (in nanoTime), ignoring interrupts (but maintaining the interrupt flag on exit).
|
boolean |
cancel(boolean b) |
java.lang.Throwable |
cause() |
protected java.lang.String |
description() |
protected <T> Future<T> |
flatMap(AbstractFuture<T> result,
java.util.function.Function<? super V,? extends Future<T>> flatMapper,
java.util.concurrent.Executor executor)
Support
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor) natively
See addListener(GenericFutureListener) for ordering semantics. |
V |
get() |
V |
get(long timeout,
java.util.concurrent.TimeUnit unit) |
V |
getNow()
if isSuccess(), returns the value, otherwise returns null
|
protected V |
getWhenDone()
Shared implementation of get() after suitable await(); assumes isDone(), and returns
either the success result or throws the suitable exception under failure
|
boolean |
isCancellable() |
boolean |
isCancelled() |
boolean |
isDone() |
boolean |
isSuccess() |
protected boolean |
isUncancellable() |
protected <T> Future<T> |
map(AbstractFuture<T> result,
java.util.function.Function<? super V,? extends T> mapper,
java.util.concurrent.Executor executor)
Support
Futures.transform(ListenableFuture, com.google.common.base.Function, Executor) natively
See addListener(GenericFutureListener) for ordering semantics. |
<T> Future<T> |
map(java.util.function.Function<? super V,? extends T> mapper)
Support
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor) natively
See addListener(GenericFutureListener) for ordering semantics. |
java.util.concurrent.Executor |
notifyExecutor() |
Future<V> |
removeListener(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener) |
Future<V> |
removeListeners(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>>... listeners) |
protected boolean |
setUncancellable() |
protected boolean |
setUncancellableExclusive() |
java.lang.String |
toString() |
protected boolean |
tryFailure(java.lang.Throwable throwable) |
protected boolean |
trySuccess(V v) |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
await, await, awaitUninterruptibly, flatMap, flatMap, map, rethrowIfFailed, sync, syncThrowUncheckedOnInterrupt, syncUninterruptibly
awaitUntil
protected static final org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder UNSET
protected static final org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder UNCANCELLABLE
protected static final org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder CANCELLED
protected AbstractFuture(org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder initialState)
public AbstractFuture()
protected AbstractFuture(V immediateSuccess)
protected AbstractFuture(java.lang.Throwable immediateFailure)
protected AbstractFuture(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener)
protected AbstractFuture(org.apache.cassandra.utils.concurrent.AbstractFuture.FailureHolder initialState, io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener)
public java.util.concurrent.Executor notifyExecutor()
protected boolean trySuccess(V v)
protected boolean tryFailure(java.lang.Throwable throwable)
protected boolean setUncancellable()
protected boolean setUncancellableExclusive()
protected boolean isUncancellable()
public boolean cancel(boolean b)
cancel
in interface java.util.concurrent.Future<V>
public boolean isSuccess()
public boolean isCancelled()
isCancelled
in interface java.util.concurrent.Future<V>
public boolean isDone()
isDone
in interface java.util.concurrent.Future<V>
public boolean isCancellable()
public java.lang.Throwable cause()
public V getNow()
protected V getWhenDone() throws java.util.concurrent.ExecutionException
java.util.concurrent.ExecutionException
public V get() throws java.lang.InterruptedException, java.util.concurrent.ExecutionException
get
in interface java.util.concurrent.Future<V>
java.lang.InterruptedException
java.util.concurrent.ExecutionException
public V get(long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException
get
in interface java.util.concurrent.Future<V>
java.lang.InterruptedException
java.util.concurrent.ExecutionException
java.util.concurrent.TimeoutException
public AbstractFuture<V> addCallback(com.google.common.util.concurrent.FutureCallback<? super V> callback)
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
natively
See addListener(GenericFutureListener)
for ordering semantics.public AbstractFuture<V> addCallback(java.util.function.BiConsumer<? super V,java.lang.Throwable> callback)
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
natively
See addListener(GenericFutureListener)
for ordering semantics.public Future<V> addCallback(java.util.function.BiConsumer<? super V,java.lang.Throwable> callback, java.util.concurrent.Executor executor)
Future
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
nativelypublic AbstractFuture<V> addCallback(com.google.common.util.concurrent.FutureCallback<? super V> callback, java.util.concurrent.Executor executor)
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
natively
See addListener(GenericFutureListener)
for ordering semantics.public AbstractFuture<V> addCallback(java.util.function.Consumer<? super V> onSuccess, java.util.function.Consumer<? super java.lang.Throwable> onFailure)
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
See addListener(GenericFutureListener)
for ordering semantics.public <T> Future<T> map(java.util.function.Function<? super V,? extends T> mapper)
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor)
natively
See addListener(GenericFutureListener)
for ordering semantics.public AbstractFuture<V> addCallback(java.util.function.Consumer<? super V> onSuccess, java.util.function.Consumer<? super java.lang.Throwable> onFailure, java.util.concurrent.Executor executor)
Futures.addCallback(com.google.common.util.concurrent.ListenableFuture<V>, com.google.common.util.concurrent.FutureCallback<? super V>, java.util.concurrent.Executor)
See addListener(GenericFutureListener)
for ordering semantics.protected <T> Future<T> map(AbstractFuture<T> result, java.util.function.Function<? super V,? extends T> mapper, @Nullable java.util.concurrent.Executor executor)
Futures.transform(ListenableFuture, com.google.common.base.Function, Executor)
natively
See addListener(GenericFutureListener)
for ordering semantics.protected <T> Future<T> flatMap(AbstractFuture<T> result, java.util.function.Function<? super V,? extends Future<T>> flatMapper, @Nullable java.util.concurrent.Executor executor)
Futures.transformAsync(ListenableFuture, AsyncFunction, Executor)
natively
See addListener(GenericFutureListener)
for ordering semantics.public Future<V> addListener(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener)
notifyExecutor()
in the order they are added (or the specified executor
in the case of addListener(Runnable, Executor)
.
if notifyExecutor()
is unset, they are invoked in the order they are added.
The ordering holds across all variants of this method.public void addListener(java.lang.Runnable task, @Nullable java.util.concurrent.Executor executor)
#executor
(or notifyExecutor()
) in the order they are added;
if notifyExecutor()
is unset, they are invoked in the order they are added.
The ordering holds across all variants of this method.addListener
in interface com.google.common.util.concurrent.ListenableFuture<V>
public void addListener(java.lang.Runnable task)
notifyExecutor()
in the order they are added (or the specified executor
in the case of addListener(Runnable, Executor)
.
if notifyExecutor()
is unset, they are invoked in the order they are added.
The ordering holds across all variants of this method.public Future<V> addListeners(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>>... listeners)
public Future<V> removeListener(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>> listener)
public Future<V> removeListeners(io.netty.util.concurrent.GenericFutureListener<? extends io.netty.util.concurrent.Future<? super V>>... listeners)
public boolean await(long timeout, java.util.concurrent.TimeUnit unit) throws java.lang.InterruptedException
Awaitable
public boolean awaitThrowUncheckedOnInterrupt(long time, java.util.concurrent.TimeUnit units) throws UncheckedInterruptedException
Awaitable
awaitThrowUncheckedOnInterrupt
in interface Awaitable
UncheckedInterruptedException
- if interruptedpublic boolean awaitUninterruptibly(long timeout, java.util.concurrent.TimeUnit unit)
Awaitable
awaitUninterruptibly
in interface Awaitable
public boolean awaitUntilThrowUncheckedOnInterrupt(long nanoTimeDeadline) throws UncheckedInterruptedException
Awaitable
awaitUntilThrowUncheckedOnInterrupt
in interface Awaitable
UncheckedInterruptedException
- if interruptedpublic boolean awaitUntilUninterruptibly(long nanoTimeDeadline)
Awaitable
awaitUntilUninterruptibly
in interface Awaitable
public Future<V> awaitUninterruptibly()
Awaitable.awaitUninterruptibly()
awaitUninterruptibly
in interface Awaitable
public Future<V> awaitThrowUncheckedOnInterrupt() throws UncheckedInterruptedException
Awaitable.awaitThrowUncheckedOnInterrupt()
awaitThrowUncheckedOnInterrupt
in interface Awaitable
UncheckedInterruptedException
- if interruptedpublic java.lang.String toString()
toString
in class java.lang.Object
protected java.lang.String description()
Copyright © 2009-2022 The Apache Software Foundation