Skip to content

Commit

Permalink
Add release notes and documentation for MoreFutures
Browse files Browse the repository at this point in the history
  • Loading branch information
dain committed May 21, 2015
1 parent f2c73e4 commit a9bde6b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Fix log levels being reset by garbage collection
- Reduce default http response buffer size from 64KB to zero bytes
- Add MoreFutures which contains utility methods for futures

* 0.109

Expand Down
12 changes: 12 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
Airlift 0.110

* Future Utilities

We've added MoreFutures class which contains utility methods for Future and
the new Java8 CompletableFuture. For basic future, there are methods for
fetching the future value with minimal exception handling. For
CompletableFuture, there are methods for easily creating futures. Finally,
we have added methods for converting to and from Guava ListenableFuture to
ease the transition to CompletableFuture (note, these methods will be removed
in a future release)

Airlift 0.109

* Default Config
Expand Down
49 changes: 49 additions & 0 deletions concurrent/src/main/java/io/airlift/concurrent/MoreFutures.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public final class MoreFutures
{
private MoreFutures() { }

/**
* Returns a future that can not be completed or canceled.
*/
public static <V> CompletableFuture<V> unmodifiableFuture(CompletableFuture<V> future)
{
requireNonNull(future, "future is null");
Expand All @@ -39,6 +42,9 @@ public static <V> CompletableFuture<V> unmodifiableFuture(CompletableFuture<V> f
return unmodifiableFuture;
}

/**
* Returns a failed future containing the specified throwable.
*/
public static <V> CompletableFuture<V> failedFuture(Throwable throwable)
{
requireNonNull(throwable, "throwable is null");
Expand All @@ -47,11 +53,24 @@ public static <V> CompletableFuture<V> failedFuture(Throwable throwable)
return future;
}

/**
* Waits for the value from the future. If the future is failed, the exception
* is thrown directly if unchecked or wrapped in a RuntimeException. If the
* thread is interrupted, the thread interruption flag is set and the original
* InterruptedException is wrapped in a RuntimeException and thrown.
*/
public static <V> V getFutureValue(Future<V> future)
{
return getFutureValue(future, RuntimeException.class);
}

/**
* Waits for the value from the future. If the future is failed, the exception
* is thrown directly if it is an instance of the specified exception type or
* unchecked, or it is wrapped in a RuntimeException. If the thread is
* interrupted, the thread interruption flag is set and the original
* InterruptedException is wrapped in a RuntimeException and thrown.
*/
public static <V, E extends Exception> V getFutureValue(Future<V> future, Class<E> exceptionType)
throws E
{
Expand All @@ -72,11 +91,28 @@ public static <V, E extends Exception> V getFutureValue(Future<V> future, Class<
}
}

/**
* Waits for the the value from the future for the specified time. If the future
* value is null, an empty Optional is still returned, and in this case the caller
* must check the future directly for the null value. If the future is failed,
* the exception is thrown directly if unchecked or wrapped in a RuntimeException.
* If the thread is interrupted, the thread interruption flag is set and the original
* InterruptedException is wrapped in a RuntimeException and thrown.
*/
public static <V> Optional<V> tryGetFutureValue(Future<V> future, int timeout, TimeUnit timeUnit)
{
return tryGetFutureValue(future, timeout, timeUnit, RuntimeException.class);
}

/**
* Waits for the the value from the future for the specified time. If the future
* value is null, an empty Optional is still returned, and in this case the caller
* must check the future directly for the null value. If the future is failed,
* the exception is thrown directly if it is an instance of the specified exception
* type or unchecked, or it is wrapped in a RuntimeException. If the thread is
* interrupted, the thread interruption flag is set and the original
* InterruptedException is wrapped in a RuntimeException and thrown.
*/
public static <V, E extends Exception> Optional<V> tryGetFutureValue(Future<V> future, int timeout, TimeUnit timeUnit, Class<E> exceptionType)
throws E
{
Expand All @@ -103,6 +139,11 @@ public static <V, E extends Exception> Optional<V> tryGetFutureValue(Future<V> f
return Optional.empty();
}

/**
* Creates a future that completes when the first future completes either normally
* or exceptionally. Cancellation of the future does not propagate to the supplied
* futures.
*/
public static <V> CompletableFuture<V> firstCompletedFuture(Iterable<? extends CompletionStage<? extends V>> futures)
{
requireNonNull(futures, "futures is null");
Expand All @@ -122,6 +163,10 @@ public static <V> CompletableFuture<V> firstCompletedFuture(Iterable<? extends C
return future;
}

/**
* Converts a ListenableFuture to a CompletableFuture. Cancellation of the
* CompletableFuture will be propagated to the ListenableFuture.
*/
public static <V> CompletableFuture<V> toCompletableFuture(ListenableFuture<V> listenableFuture)
{
requireNonNull(listenableFuture, "listenableFuture is null");
Expand Down Expand Up @@ -151,6 +196,10 @@ public void onFailure(Throwable t)
return future;
}

/**
* Converts a CompletableFuture to a ListenableFuture. Cancellation of the
* ListenableFuture will be propagated to the CompletableFuture.
*/
public static <V> ListenableFuture<V> toListenableFuture(CompletableFuture<V> completableFuture)
{
requireNonNull(completableFuture, "completableFuture is null");
Expand Down

0 comments on commit a9bde6b

Please sign in to comment.