1 /*
2 * The contents of this file are subject to the terms of the Common Development and
3 * Distribution License (the License). You may not use this file except in compliance with the
4 * License.
5 *
6 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7 * specific language governing permission and limitations under the License.
8 *
9 * When distributing Covered Software, include this CDDL Header Notice in each file and include
10 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11 * Header, with the fields enclosed by brackets [] replaced by your own identifying
12 * information: "Portions copyright [year] [name of copyright owner]".
13 *
14 * Copyright 2015-2016 ForgeRock AS.
15 */
16 package org.forgerock.util.promise;
17
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.TimeoutException;
22
23 import org.forgerock.util.AsyncFunction;
24 import org.forgerock.util.Function;
25
26 /**
27 * A {@code Promise} represents the result of an asynchronous task.
28 *
29 * @param <V>
30 * The type of the task's result, or {@link Void} if the task does
31 * not return anything (i.e. it only has side-effects).
32 * @param <E>
33 * The type of the exception thrown by the task if it fails, or
34 * {@link NeverThrowsException} if the task cannot fail.
35 * @see PromiseImpl
36 * @see Promises
37 */
38 public interface Promise<V, E extends Exception> extends Future<V> {
39 // TODO: progressible promise
40
41 /**
42 * Attempts to cancel the asynchronous task associated with this
43 * {@code Promise}. Cancellation will fail if this {@code Promise} has
44 * already completed or has already been cancelled. If successful, then
45 * cancellation will complete this {@code Promise} with an appropriate
46 * exception and notify any registered functions and completion handlers.
47 * <p>
48 * After this method returns, subsequent calls to {@link #isDone} will
49 * always return {@code true}. Subsequent calls to {@link #isCancelled} will
50 * always return {@code true} if this method returned {@code true}.
51 *
52 * @param mayInterruptIfRunning
53 * {@code true} if the thread executing executing the response
54 * handler should be interrupted; otherwise, in-progress response
55 * handlers are allowed to complete.
56 * @return {@code false} if {@code Promise} could not be cancelled,
57 * typically because it has already completed normally; {@code true}
58 * otherwise.
59 */
60 @Override
61 boolean cancel(boolean mayInterruptIfRunning);
62
63 /**
64 * Waits if necessary for this {@code Promise} to complete, and then returns
65 * the result if it completed successfully, or throws an
66 * {@code ExecutionException} containing the cause of the failure.
67 *
68 * @return The result, but only if this {@code Promise} completed
69 * successfully.
70 * @throws ExecutionException
71 * If this {@code Promise} was cancelled or did not complete
72 * successfully. The {@code ExecutionException} will contain the
73 * cause of the failure.
74 * @throws InterruptedException
75 * If the current thread was interrupted while waiting.
76 */
77 @Override
78 V get() throws ExecutionException, InterruptedException;
79
80 /**
81 * Waits if necessary for at most the given time for this {@code Promise} to
82 * complete, and then returns the result if it completed successfully, or
83 * throws an {@code ExecutionException} containing the cause of the failure.
84 *
85 * @param timeout
86 * The maximum time to wait.
87 * @param unit
88 * The time unit of the timeout argument.
89 * @return The result, but only if this {@code Promise} completed
90 * successfully.
91 * @throws ExecutionException
92 * If this {@code Promise} was cancelled or did not complete
93 * successfully. The {@code ExecutionException} will contain the
94 * cause of the failure.
95 * @throws TimeoutException
96 * If the wait timed out.
97 * @throws InterruptedException
98 * If the current thread was interrupted while waiting.
99 */
100 @Override
101 V get(long timeout, TimeUnit unit) throws ExecutionException, TimeoutException,
102 InterruptedException;
103
104 /**
105 * Waits if necessary for this {@code Promise} to complete, and then returns
106 * the result if it completed successfully, or throws an exception
107 * representing the cause of the failure.
108 *
109 * @return The result, but only if this {@code Promise} completed
110 * successfully.
111 * @throws E
112 * If this {@code Promise} was cancelled or did not complete
113 * successfully.
114 * @throws InterruptedException
115 * If the current thread was interrupted while waiting.
116 */
117 V getOrThrow() throws InterruptedException, E;
118
119 /**
120 * Waits if necessary for at most the given time for this {@code Promise} to
121 * complete, and then returns the result if it completed successfully, or
122 * throws an exception representing the cause of the failure.
123 *
124 * @param timeout
125 * The maximum time to wait.
126 * @param unit
127 * The time unit of the timeout argument.
128 * @return The result, but only if this {@code Promise} completed
129 * successfully.
130 * @throws E
131 * If this {@code Promise} was cancelled or did not complete
132 * successfully.
133 * @throws TimeoutException
134 * If the wait timed out.
135 * @throws InterruptedException
136 * If the current thread was interrupted while waiting.
137 */
138 V getOrThrow(long timeout, TimeUnit unit) throws InterruptedException, E, TimeoutException;
139
140 /**
141 * Waits if necessary for this {@code Promise} to complete, and then returns
142 * the result if it completed successfully, or throws an exception
143 * representing the cause of the failure.
144 * <p>
145 * This method is similar to {@link #getOrThrow()} except that it will
146 * ignore thread interrupts. When this method returns the status of the
147 * current thread will be interrupted if an interrupt was received while
148 * waiting.
149 *
150 * @return The result, but only if this {@code Promise} completed
151 * successfully.
152 * @throws E
153 * If this {@code Promise} was cancelled or did not complete
154 * successfully.
155 */
156 V getOrThrowUninterruptibly() throws E;
157
158 /**
159 * Waits if necessary for at most the given time for this {@code Promise} to
160 * complete, and then returns the result if it completed successfully, or
161 * throws an exception representing the cause of the failure.
162 * <p>
163 * This method is similar to {@link #getOrThrow(long, TimeUnit)} except that
164 * it will ignore thread interrupts. When this method returns the status of
165 * the current thread will be interrupted if an interrupt was received while
166 * waiting.
167 *
168 * @param timeout
169 * The maximum time to wait.
170 * @param unit
171 * The time unit of the timeout argument.
172 * @return The result, but only if this {@code Promise} completed
173 * successfully.
174 * @throws E
175 * If this {@code Promise} was cancelled or did not complete
176 * successfully.
177 * @throws TimeoutException
178 * If the wait timed out.
179 */
180 V getOrThrowUninterruptibly(long timeout, TimeUnit unit) throws E, TimeoutException;
181
182 /**
183 * Returns {@code true} if this {@code Promise} was cancelled before it
184 * completed normally.
185 *
186 * @return {@code true} if this {@code Promise} was cancelled before it
187 * completed normally, otherwise {@code false}.
188 */
189 @Override
190 boolean isCancelled();
191
192 /**
193 * Returns {@code true} if this {@code Promise} has completed.
194 * <p>
195 * Completion may be due to normal termination, an exception, or
196 * cancellation. In all of these cases, this method will return {@code true}.
197 *
198 * @return {@code true} if this {@code Promise} has completed, otherwise
199 * {@code false}.
200 */
201 @Override
202 boolean isDone();
203
204 /**
205 * Registers the provided completion handler for notification if this
206 * {@code Promise} cannot be completed due to an exception. If this
207 * {@code Promise} completes with a result then the completion handler
208 * will not be notified.
209 * <p>
210 * This method can be used for asynchronous completion notification.
211 *
212 * @param onException
213 * The completion handler which will be notified upon failure
214 * completion of this {@code Promise}.
215 * @return This {@code Promise}.
216 */
217 Promise<V, E> thenOnException(ExceptionHandler<? super E> onException);
218
219 /**
220 * Registers the provided completion handler for notification once this
221 * {@code Promise} has completed with a result. If this {@code Promise}
222 * completes with an exception then the completion handler will not be
223 * notified.
224 * <p>
225 * This method can be used for asynchronous completion notification and is
226 * equivalent to {@link #then(Function)}.
227 *
228 * @param onResult
229 * The completion handler which will be notified upon successful
230 * completion of this {@code Promise}.
231 * @return This {@code Promise}.
232 */
233 Promise<V, E> thenOnResult(ResultHandler<? super V> onResult);
234
235 /**
236 * Registers the provided completion handlers for notification once this
237 * {@code Promise} has completed (with a result or an exception). If this
238 * {@code Promise} completes with a result then {@code onResult} will be
239 * notified with the result, otherwise {@code onException} will be notified
240 * with the exception that occurred.
241 * <p>
242 * This method can be used for asynchronous completion notification.
243 *
244 * @param onResult
245 * The completion handler which will be notified upon completion
246 * with a result of this {@code Promise}.
247 * @param onException
248 * The completion handler which will be notified upon failure of
249 * this {@code Promise}.
250 * @return This {@code Promise}.
251 */
252 Promise<V, E> thenOnResultOrException(ResultHandler<? super V> onResult, ExceptionHandler<? super E> onException);
253
254 /**
255 * Submits the provided runnable for execution once this {@code Promise} has
256 * completed, and regardless of whether it has a result or an exception.
257 * <p>
258 * This method can be used for resource cleanup after a series of
259 * asynchronous tasks have completed. More specifically, this method should
260 * be used in a similar manner to {@code finally} statements in
261 * {@code try...catch} expressions.
262 * <p>
263 * This method is equivalent to {@link #thenAlways(Runnable)}.
264 *
265 * @param onResultOrException
266 * The runnable which will be notified regardless of the final
267 * outcome of this {@code Promise}.
268 * @return This {@code Promise}.
269 */
270 Promise<V, E> thenOnResultOrException(Runnable onResultOrException);
271
272 /**
273 * Submits the provided function for execution once this {@code Promise} has
274 * completed with a result, and returns a new {@code Promise} representing
275 * the outcome of the function. If this {@code Promise} does not
276 * complete with a result then the function will not be invoked and the exception
277 * will be forwarded to the returned {@code Promise}.
278 * <p>
279 * This method can be used for transforming the result of an asynchronous
280 * task.
281 *
282 * @param <VOUT>
283 * The type of the function's result, or {@link Void} if the
284 * function does not return anything (i.e. it only has
285 * side-effects). Note that the type may be different to the type
286 * of this {@code Promise}.
287 * @param onResult
288 * The function which will be executed upon successful completion
289 * of this {@code Promise}.
290 * @return A new {@code Promise} representing the outcome of the
291 * function.
292 */
293 <VOUT> Promise<VOUT, E> then(Function<? super V, VOUT, E> onResult);
294
295 /**
296 * Submits the provided function for execution once this {@code Promise} has
297 * not completed with a result (has completed with an exception), and returns
298 * a new {@code Promise} representing the outcome of the function.
299 * If this {@code Promise} completes with a result then the function will not
300 * be invoked and the result notification will be forwarded to the returned
301 * {@code Promise}.
302 * <p>
303 * This method can be used for transforming the result of an asynchronous
304 * task.
305 *
306 * @param <EOUT>
307 * The type of the exception thrown by the function if it
308 * fails, or {@link NeverThrowsException} if it cannot fails.
309 * Note that the type may be different to the type of this
310 * {@code Promise}.
311 * @param onException
312 * The function which will be executed upon failure completion
313 * of this {@code Promise}.
314 * @return A new {@code Promise} representing the outcome of the
315 * function.
316 */
317 <EOUT extends Exception> Promise<V, EOUT> thenCatch(Function<? super E, V, EOUT> onException);
318
319 /**
320 * Submits the provided function for execution once this {@code Promise} has
321 * not completed with a result nor with an exception but with a {@link RuntimeException}, and returns
322 * a new {@code Promise} representing the outcome of the function.
323 * If this {@code Promise} completes with a result or an exception then the function will not
324 * be invoked and the result notification will be forwarded to the returned
325 * {@code Promise}.
326 * <p>
327 * This method can be used for transforming the result of an asynchronous
328 * task.
329 *
330 * @param onRuntimeException
331 * The function which will be executed upon failure completion
332 * of this {@code Promise}.
333 * @return A new {@code Promise} representing the outcome of the
334 * function.
335 */
336 Promise<V, E> thenCatchRuntimeException(Function<? super RuntimeException, V, E> onRuntimeException);
337
338 /**
339 * Submits the provided asynchronous function for execution once this
340 * {@code Promise} has completed with a {@link RuntimeException}, and returns a new
341 * {@code Promise} representing the outcome of the function. If this
342 * {@code Promise} completes with a result or the typed exception then the
343 * completion asynchronous function will not be called.
344 * <p>
345 * This method may be used for chaining together a series of asynchronous
346 * tasks.
347 *
348 * @param onRuntimeException
349 * The asynchronous function which will be executed upon failure completion
350 * with a {@link RuntimeException} of this {@code Promise}.
351 *
352 * @return A new {@code Promise} representing the outcome of the
353 * function.
354 */
355 Promise<V, E> thenCatchRuntimeExceptionAsync(AsyncFunction<? super RuntimeException, V, E> onRuntimeException);
356
357 /**
358 * Submits the provided functions for execution once this {@code Promise}
359 * has completed (with a result or an exception), and returns a new
360 * {@code Promise} representing the outcome of the invoked function. If
361 * this {@code Promise} completes with a result then {@code onResult}
362 * will be invoked with the result, otherwise {@code onException} will
363 * be invoked with the exception that occurred.
364 * <p>
365 * This method can be used for transforming the outcome of an
366 * asynchronous task.
367 *
368 * @param <VOUT>
369 * The type of the functions' result, or {@link Void} if the
370 * functions do not return anything (i.e. they only have
371 * side-effects). Note that the type may be different to the type
372 * of this {@code Promise}.
373 * @param <EOUT>
374 * The type of the exception thrown by the functions if they
375 * fail, or {@link NeverThrowsException} if they cannot fail.
376 * Note that the type may be different to the type of this
377 * {@code Promise}.
378 * @param onResult
379 * The function which will be executed upon successful completion
380 * of this {@code Promise}.
381 * @param onException
382 * The function which will be executed upon failure of this
383 * {@code Promise}.
384 * @return A new {@code Promise} representing the outcome of the
385 * invoked function.
386 */
387 <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> then(
388 Function<? super V, VOUT, EOUT> onResult, Function<? super E, VOUT, EOUT> onException);
389
390 /**
391 * Submits the provided functions for execution once this {@code Promise}
392 * has completed (with a result or an exception or a {@link RuntimeException}), and returns a new
393 * {@code Promise} representing the outcome of the invoked function. If
394 * this {@code Promise} completes with a result then {@code onResult}
395 * will be invoked with the result, with a {@link RuntimeException} then {@code onRuntimeException}
396 * will be invoked with the runtime exception that occurred, otherwise {@code onException} will
397 * be invoked with the exception that occurred.
398 * <p>
399 * This method can be used for transforming the outcome of an
400 * asynchronous task.
401 *
402 * @param <VOUT>
403 * The type of the functions' result, or {@link Void} if the
404 * functions do not return anything (i.e. they only have
405 * side-effects). Note that the type may be different to the type
406 * of this {@code Promise}.
407 * @param <EOUT>
408 * The type of the exception thrown by the functions if they
409 * fail, or {@link NeverThrowsException} if they cannot fail.
410 * Note that the type may be different to the type of this
411 * {@code Promise}.
412 * @param onResult
413 * The function which will be executed upon successful completion
414 * of this {@code Promise}.
415 * @param onException
416 * The function which will be executed upon failure of this
417 * {@code Promise}.
418 * @param onRuntimeException
419 * The function which will be executed upon failure with
420 * {@link RuntimeException} of this {@code Promise}.
421 * @return A new {@code Promise} representing the outcome of the
422 * invoked function.
423 */
424 <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> then(
425 Function<? super V, VOUT, EOUT> onResult, Function<? super E, VOUT, EOUT> onException,
426 Function<? super RuntimeException, VOUT, EOUT> onRuntimeException);
427
428
429 /**
430 * Submits the provided runnable for execution once this {@code Promise} has
431 * completed, and regardless of whether it has a result or an exception.
432 * <p>
433 * This method can be used for resource cleanup after a series of
434 * asynchronous tasks have completed. More specifically, this method should
435 * be used in a similar manner to {@code finally} statements in
436 * {@code try...catch} expressions.
437 * <p>
438 * This method is equivalent to {@link #thenOnResultOrException(Runnable)}.
439 *
440 * @param onResultOrException
441 * The runnable which will be notified regardless of the final
442 * outcome of this {@code Promise}.
443 * @return This {@code Promise}.
444 */
445 Promise<V, E> thenAlways(Runnable onResultOrException);
446
447 /**
448 * Submits the provided runnable for execution once this {@code Promise} has
449 * completed, and regardless of whether of its outcome.
450 * <p>
451 * This method can be used for resource cleanup after a series of
452 * asynchronous tasks have completed. More specifically, this method should
453 * be used in a similar manner to {@code finally} statements in
454 * {@code try...catch} expressions.
455 * <p>
456 * This method is equivalent to {@link #thenAlways(Runnable)}.
457 *
458 * @param onResultOrException
459 * The runnable which will be notified regardless of the final
460 * outcome of this {@code Promise}.
461 * @return This {@code Promise}.
462 */
463 Promise<V, E> thenFinally(Runnable onResultOrException);
464
465 /**
466 * Submits the provided asynchronous function for execution once this
467 * {@code Promise} has completed with a result, and returns a new
468 * {@code Promise} representing the outcome of the function. If
469 * this {@code Promise} complete with an exception then the function
470 * will not be invoked and the error will be forwarded to the returned
471 * {@code Promise}.
472 * <p>
473 * This method may be used for chaining together a series of asynchronous
474 * tasks.
475 *
476 * @param <VOUT>
477 * The type of the function's result, or {@link Void} if the
478 * function does not return anything (i.e. it only has
479 * side-effects). Note that the type may be different to the type
480 * of this {@code Promise}.
481 * @param onResult
482 * The asynchronous function which will be executed upon
483 * successful completion of this {@code Promise}.
484 * @return A new {@code Promise} representing the outcome of the
485 * function.
486 */
487 <VOUT> Promise<VOUT, E> thenAsync(AsyncFunction<? super V, VOUT, E> onResult);
488
489 /**
490 * Submits the provided asynchronous function for execution once this
491 * {@code Promise} has completed with an exception, and returns a new
492 * {@code Promise} representing the outcome of the function. If
493 * this {@code Promise} completes with a result then the function
494 * will not be invoked and the exception will be forwarded to the returned
495 * {@code Promise}.
496 * <p>
497 * This method may be used for chaining together a series of asynchronous
498 * tasks.
499 *
500 * @param <EOUT>
501 * The type of the exception thrown by the function if it
502 * fails, or {@link NeverThrowsException} if it cannot fails.
503 * Note that the type may be different to the type of this
504 * {@code Promise}.
505 * @param onException
506 * The asynchronous function which will be executed upon failure completion
507 * of this {@code Promise}.
508 *
509 * @return A new {@code Promise} representing the outcome of the
510 * function.
511 */
512 <EOUT extends Exception> Promise<V, EOUT> thenCatchAsync(AsyncFunction<? super E, V, EOUT> onException);
513
514 /**
515 * Submits the provided asynchronous functions for execution once this
516 * {@code Promise} has completed, and returns a new {@code Promise}
517 * representing the outcome of the invoked function. If this
518 * {@code Promise} completes with a result then {@code onResult} will be
519 * invoked with the result, otherwise {@code onException} will be invoked with
520 * the exception that occurred.
521 * <p>
522 * This method may be used for chaining together a series of asynchronous
523 * tasks.
524 *
525 * @param <VOUT>
526 * The type of the functions' result, or {@link Void} if the
527 * functions do not return anything (i.e. they only have
528 * side-effects). Note that the type may be different to the type
529 * of this {@code Promise}.
530 * @param <EOUT>
531 * The type of the exception thrown by the functions if they
532 * fail, or {@link NeverThrowsException} if they cannot fail.
533 * Note that the type may be different to the type of this
534 * {@code Promise}.
535 * @param onResult
536 * The asynchronous function which will be executed upon
537 * successful completion of this {@code Promise}.
538 * @param onException
539 * The asynchronous function which will be executed upon failure
540 * of this {@code Promise}.
541 * @return A new {@code Promise} representing the outcome of the
542 * invoked function.
543 */
544 <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> thenAsync(
545 AsyncFunction<? super V, VOUT, EOUT> onResult,
546 AsyncFunction<? super E, VOUT, EOUT> onException);
547
548 /**
549 * Submits the provided asynchronous functions for execution once this
550 * {@code Promise} has completed, and returns a new {@code Promise}
551 * representing the outcome of the invoked function. If this
552 * {@code Promise} completes with a result then {@code onResult} will be
553 * invoked with the result, otherwise {@code onException} will be invoked with
554 * the exception that occurred, or {@code onRuntimeException} will be invoked with
555 * the runtime exception that occurred.
556 * <p>
557 * This method may be used for chaining together a series of asynchronous
558 * tasks.
559 *
560 * @param <VOUT>
561 * The type of the functions' result, or {@link Void} if the
562 * functions do not return anything (i.e. they only have
563 * side-effects). Note that the type may be different to the type
564 * of this {@code Promise}.
565 * @param <EOUT>
566 * The type of the exception thrown by the functions if they
567 * fail, or {@link NeverThrowsException} if they cannot fail.
568 * Note that the type may be different to the type of this
569 * {@code Promise}.
570 * @param onResult
571 * The asynchronous function which will be executed upon
572 * successful completion of this {@code Promise}.
573 * @param onException
574 * The asynchronous function which will be executed upon failure
575 * of this {@code Promise}.
576 * @param onRuntimeException
577 * The asynchronous function which will be executed upon failure
578 * with {@link RuntimeException} of this {@code Promise}.
579 * @return A new {@code Promise} representing the outcome of the
580 * invoked function.
581 */
582 <VOUT, EOUT extends Exception> Promise<VOUT, EOUT> thenAsync(
583 AsyncFunction<? super V, VOUT, EOUT> onResult,
584 AsyncFunction<? super E, VOUT, EOUT> onException,
585 AsyncFunction<? super RuntimeException, VOUT, EOUT> onRuntimeException);
586
587 /**
588 * Registers the provided completion handler for notification if this
589 * {@code Promise} cannot be completed due to an runtime exception. If this
590 * {@code Promise} completes with a result or the typed exception then the
591 * completion handler will not be notified.
592 * <p>
593 * This method can be used for asynchronous completion notification.
594 *
595 * @param onRuntimeException
596 * The completion handler which will be notified upon an
597 * uncaught runtime exception completion of this
598 * {@code Promise}.
599 * @return This {@code Promise}.
600 */
601 Promise<V, E> thenOnRuntimeException(RuntimeExceptionHandler onRuntimeException);
602 }