All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atlassian.util.concurrent.Promise Maven / Gradle / Ivy

Go to download

This project contains utility classes that are used by various products and projects inside Atlassian and may have some utility to the world at large.

There is a newer version: 4.0.1
Show newest version
/**
 * Copyright 2012 Atlassian Pty Ltd 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package io.atlassian.util.concurrent;

import javax.annotation.Nonnull;
import java.util.concurrent.Future;

import java.util.function.Consumer;
import java.util.function.Function;

/**
 * A promise that presents a nicer interface to
 * {@link java.util.concurrent.Future}. It can be claimed without needing to
 * catch checked exceptions, and it may be mapped to new types of Promise via
 * the {@link #map(Function)} and {@link #flatMap(Function)} methods.
 * 

* For instance, if you have a Promise<A> and you want to do * some operation on the value (an A) you can use {@link #map(Function)} to turn * this into a Promise of some other type. Let's say you get back a * Person and you really only need their surname: * *

 * public Promise<String> fetchSurname(PersonId id) {
 *   Promise<Person> promise asyncClient.fetchPerson(id);
 *   return promise.map(new Function<Person, String>() {
 *     public String apply(Person p) {
 *       return p.surname();
 *     }
 *   };
 * }
 * 
*

* If you want to do some further asynchronous operation using the value, you * can use {@link #flatMap(Function)} to turn this into a Promise of some other * type. Let's say you get back a Person and you really only need * to perform a further query to get their address: * *

 * public Promise<Address> fetchAddress(PersonId id) {
 *   Promise<Person> promise asyncClient.fetchPerson(id);
 *   return promise.flatMap(new Function<Person, Promise<Address>>() {
 *     public Promise<Address> apply(Person p) {
 *       return asyncClient.fetchAddress(p.addressId());
 *     }
 *   };
 * }
 * 
*

* Note that there are a number of handy utility functions for creating * Promise objects on the * {@link io.atlassian.util.concurrent.Promises} companion. *

* Cancelling a Promise that hasn't yet been completed will do it with a * {@link java.util.concurrent.CancellationException} and that will propagate to * dependent Promises. But cancelling a dependent Promise will not cancel the * original one. * * @since 2.4 */ public interface Promise extends Future { /** * Blocks the thread waiting for a result. Exceptions are thrown as runtime * exceptions. * * @return The promised object */ A claim(); /** * Registers a callback to be called when the promised object is available. * May not be executed in the same thread as the caller. * * @param c The consumer to call with the result * @return This object for chaining */ Promise done(Consumer c); /** * Registers a callback to be called when an exception is thrown. May not be * executed in the same thread as the caller. * * @param c The consumer to call with the throwable * @return This object for chaining */ Promise fail(Consumer c); /** * Registers a TryConsumer to handle both success and failure (exception) * cases. May not be executed in the same thread as the caller. *

* See {@link Promises#compose(Consumer, Consumer)} * * @param callback The future callback * @return This object for chaining */ Promise then(TryConsumer callback); /** * Transforms this {@link io.atlassian.util.concurrent.Promise} from one type * to another by way of a transformation function. *

* * @param function The transformation function * @return A new promise resulting from the transformation * @param a B. */ Promise map(Function function); /** * Transforms this promise from one type to another by way of a transformation * function that returns a new Promise, leaving the strategy for that promise * production up to the function. *

* Note this is known as flatMap as it first maps to a * Promise<Promise<A>> and then flattens that out * into a single layer Promise. * * @param function The transformation function to a new Promise value * @return A new promise resulting from the transformation * @param a B. */ Promise flatMap(Function> function); /** * Recover from an exception using the supplied exception strategy * * @param handleThrowable rehabilitate the exception with a value of type B * @return A new promise that will not throw an exception (unless * handleThrowable itself threw). */ Promise recover(Function handleThrowable); /** * Transform this promise from one type to another, also providing a strategy * for dealing with any exceptions encountered. * * @param handleThrowable rehabilitate the exception with a value of type B * @param function mapping function * @return A new promise resulting from the catamorphic transformation. This * promise will not throw an exception (unless handleThrowable itself threw). * @param a B. */ Promise fold(Function handleThrowable, Function function); /** * Consumer interface to be called after a promise is fulfilled with a * succesful value or a failure. * * @param type of the successful value. */ interface TryConsumer extends Consumer { void fail(@Nonnull Throwable t); } }