public class Promise<T> extends Object
public T findSomething(Args args);then this method should be represented in promise-oriented way like this:
public Promise<T> findSomethingPromise(Args args);
In this case, the call to findSomething(args)
is semantically equivalent to
findSomethingPromise(args).
. There may be service-specific difference between
those two forms of invocation. If await
()findSomething
throws exception, then await
wraps them into PromiseException
. If findSomething
consults some kind of local cache with subscription,
then it may be defined by the service to return immediately and only retrieve the result from the cache, while
findSomethingPromise
is a proper form that makes potentially time-consuming call to a back end data provider.
findSomethingPromise
via findSomething
using an Executor
for
background computation looks like this:
public Promise<T> findSomethingPromise(Args args) { Promise<T> promise = newA more advanced implementation may also cancel pending and/or ongoing computation when client cancels the promise or times out waiting for a promise to be completed. The sketch of such implementation using anPromise
<T>(); executor.execute
(() -> { try { T result = findSomething(args); promise.complete
(result); } catch (Throwable t) { promise.completeExceptionally
(t); } }); return promise; }
ExecutorService
is:
public Promise<T> findSomethingPromise(Args args) { Promise<T> promise = newPromise
<T>(); Future<?> future = executor.submit
(() -> { try { T result = findSomething(args); promise.complete
(result); } catch (Throwable t) { promise.completeExceptionally
(t); } }); promise.whenDone(p -> future.cancel
(true)); // true to interrupt running task return promise; }
try {
findSomething(args).await
();
handleResult(result);
} catch (Throwable t) {
handleException(t);
}
Waiting with timeout is performed by replacing await
call with await(timeout, unit)
.
The same handling can be performed in the service provider thread like this:
findSomething(args).whenDone(promise -> { if (promise.hasResult()) handleResult(promise.getResult()); else handleException(promise.getException()); });
What \ State | Initial | Result | Exception | Cancelled |
---|---|---|---|---|
Transition method | constructor |
complete |
completeExceptionally |
cancel |
isDone |
false |
true |
true |
true |
hasResult |
false |
true |
false |
false |
hasException |
false |
false |
true |
true |
isCancelled |
false |
false |
false |
true |
getResult |
null |
result |
null |
null |
getException |
null |
null |
exception |
CancellationException |
By default, whenDone
notifications are performed in the same thread that
invoked the state-changing method like complete
,
completeExceptionally
, or cancel
.
Promise
class can be extended to override protected handleDone
method to move notification to other threads, for example, or to do other kind of processing.
PromiseHandler
, while at the same time
supporting multiple invocations of whenDone
at the cost of extra
memory consumption. Performance-sensitive service implementations that need to cancel their internal computation
on the promise cancel are encouraged to extend Promise
class and override handleDone
for
this purpose instead of using whenDone
.
Promises
class for utility methods that combine multiple Promise
instances to
facilitate batch processing and concurrent invocations.
Future
and CompletableFuture
. However, the methods
in this class are carefully selected to minimize the interface weight and the preference is given to methods
that do no throw checked exceptions. All the names of the methods are picked to avoid conflicts with
CompletionStage
, so this class can be potentially enhanced to implement CompletionStage
while maintaining backwards compatibility.Constructor and Description |
---|
Promise()
Creates promise in the initial state and without an executor for notifications.
|
Modifier and Type | Method and Description |
---|---|
T |
await()
Wait for computation to complete and return its result or throw an exception in case of exceptional completion.
|
T |
await(long timeout,
TimeUnit unit)
Wait for computation to complete or timeout and return its result or throw an exception in case of exceptional completion or timeout.
|
boolean |
awaitWithoutException(long timeout,
TimeUnit unit)
Wait for computation to complete or timeout or throw an exception in case of exceptional completion.
|
void |
cancel()
Cancels computation.
|
void |
complete(T result)
Completes computation normally with a specified result.
|
static <T> Promise<T> |
completed(T result)
Returns new promise that is
completed with a specified result. |
void |
completeExceptionally(Throwable exception)
Completes computation exceptionally with a specified exception.
|
static <T> Promise<T> |
failed(Throwable exception)
Returns new promise that is
completed exceptionally with a
specified exception. |
Throwable |
getException()
Returns exceptional outcome of computation.
|
T |
getResult()
Returns result of computation.
|
protected void |
handleDone(PromiseHandler<? super T> handler)
Invoked when promise is done.
|
boolean |
hasException()
Returns
true when computation has completed exceptionally or was cancelled. |
boolean |
hasResult()
Returns
true when computation has completed normally. |
boolean |
isCancelled()
Returns
true when computation was cancelled . |
boolean |
isDone()
|
void |
whenDone(PromiseHandler<? super T> handler)
Registers a handler to be invoked exactly once when computation
completes . |
void |
whenDoneAsync(PromiseHandler<? super T> handler,
Executor executor)
Registers a handler to be invoked asynchronously exactly once when computation
completes . |
public Promise()
public final boolean isDone()
true
when computation has completed.public final boolean hasResult()
true
when computation has completed normally.
Use getResult()
method to get the result of the computation.true
when computation has completed normally.getResult()
public final boolean hasException()
true
when computation has completed exceptionally or was cancelled.
Use getException()
method to get the exceptional outcome of the computation.true
when computation has completed exceptionally or was cancelled.public final boolean isCancelled()
true
when computation was cancelled
.
Use getException()
method to get the corresponding CancellationException
.true
when computation was cancelled.cancel()
,
getException()
public final T getResult()
result
, then
this method returns null
.hasResult()
public final Throwable getException()
exception
,
then this method returns null
. If computation has completed exceptionally or was cancelled, then
the result of this method is not null
.
If computation was cancelled
, then this method returns an
instance of CancellationException
.hasException()
public final T await()
interrupted
, then the computation is cancelled,
the interruption flag on the current thread is set, and CancellationException
is thrown.
This method waits forever. See await(timeout, unit)
for a timed wait
when the result of this promise is required to proceed or
awaitWithoutException(timeout, unit)
when the result
is not required and the normal execution shall continue on timeout.
CancellationException
- if computation was cancelled.PromiseException
- if computation has completed exceptionally.public final T await(long timeout, TimeUnit unit)
interrupted
, then the computation is cancelled
,
the interruption flag on the current thread is set, and CancellationException
is thrown.
If the wait times out, then the computation is cancelled
and CancellationException
is thrown.
Use this method in the code that must get and process the result of this promise, which is returned
by this method when it completes normally. When the result is not required and the normal execution shall
continue on timeout use awaitWithoutException
.
CancellationException
- if computation was cancelled or timed out.PromiseException
- if computation has completed exceptionally.public final boolean awaitWithoutException(long timeout, TimeUnit unit)
interrupted
, then the computation is cancelled
,
the interruption flag on the current thread is set, and CancellationException
is thrown.
If the wait times out, then the computation is cancelled
and this method returns false
.
Use this method in the code that shall continue normal execution in case of timeout.
true
if the computation has completed normally; false
when wait timed out.CancellationException
- if computation was cancelled.PromiseException
- if computation has completed exceptionally.public final void cancel()
completed
.
If cancelled, then getException
will return CancellationException
,
isDone
, isCancelled
, and hasException
will return true
,
all handlers
that were installed with whenDone
method
are notified by
invoking their promiseDone
method, and
all waiters on join
method throw CancellationException
.
public final void complete(T result)
completed
(normally, exceptionally, or was cancelled),
If completed, then getResult
will return the specified result,
isDone
and hasResult
will return true
,
all handlers
that were installed with whenDone
method
are notified by invoking their promiseDone
method, and
all waiters on join
method return the result.
result
- the result of computation.getResult()
public final void completeExceptionally(Throwable exception)
completed
,
otherwise getException()
will return the specified exception.
If completed exceptionally, then getException
will return the specified exception,
isDone
and hasException
will return true
,
all handlers
that were installed with whenDone
method
are notified by invoking their promiseDone
method, and
all waiters on join
method throw PromiseException
wrapping this exception.
exception
- the exception.NullPointerException
- if exception is null.getException()
public final void whenDone(PromiseHandler<? super T> handler)
completes
.
The handler's promiseDone
method
is invoked immediately when this computation has already completed,
otherwise it will be invoked synchronously in the future when computation
completes normally
,
or exceptionally
,
or is cancelled
from the same thread that had invoked one of the completion methods.
Exceptions that are produced by the invocation of
PromiseHandler.promiseDone
method
are caught and logged.handler
- the handler.NullPointerException
- if handler is null.public final void whenDoneAsync(PromiseHandler<? super T> handler, Executor executor)
completes
.
This method is a shortcut for the following code:
whenDone
(new PromiseHandler<T>() {
public void promiseDone(Promise<? extends T> promise) {
executor.execute(new Runnable() {
public void run() {
handler.promiseDone(Promise.this);
}
});
}
});
handler
- the handler.executor
- the executor.NullPointerException
- if handler or executor is null.public static <T> Promise<T> completed(T result)
completed
with a specified result.T
- the result type.result
- the result of computation.completed
with a specified result.public static <T> Promise<T> failed(Throwable exception)
completed exceptionally
with a
specified exception.T
- the result type.exception
- the exception.completed exceptionally
with a
specified exception.NullPointerException
- if exception is null.protected void handleDone(PromiseHandler<? super T> handler)
PromiseHandler.promiseDone
on all handlers.handler
- reference to installed handlers list or null
when no handlers were set.Copyright © 2002–2023 Devexperts LLC. All rights reserved.