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 }