javascalautils.concurrent.Promise Maven / Gradle / Ivy
/**
* Copyright 2015 Peter Nerg
*
* 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 javascalautils.concurrent;
import javascalautils.Failure;
import javascalautils.Success;
import javascalautils.Try;
/**
* The Promise is the promise to deliver a value at some time in the future.
* This is the handle the actual computation side of of the job uses.
* Once a job is finished it will report the outcome to the Promise which in turn relays it to the Future the client/application is monitoring.
* A promise can be fulfilled either by invoking success or failure but not both.
* Nor can {@link #success(Object) success}/{@link #failure(Throwable) failure} be invoked twice.
* The principle is that a {@link Promise} will deliver exactly one successful or failure response.
* The successful response is of any type whilst the failure is expected to be of type (or subclass of) {@link Throwable}.
*
* Together with a {@link Future} this allows a safe publication of asynchronously calculated results into another thread.
* The basic principle is to first create a {@link Promise}.
* Promise<String> promise = Promise.apply();
Using that instance one can get hold of the {@link Future} that is the container
* for the value-to-be.
* Future<String> future = promise.future();
To complete the Promise and by extension completing the Future one can use any of
* several methods:
*
* - {@link #success(Object)}
* - {@link #failure(Throwable)}
* - {@link #complete(Try)}
* - {@link #completeWith(Future)}
*
* E.g. promise.success("Peter was here");
Note that only one of the methods may be invoked as the Promise can only be fulfilled
* once.
* The above methods come with a variant tryNNN which allows for multiple invocations without raising an exception.
* Though still only the first invocation/completion counts.
*
* @author Peter Nerg
* @since 1.2
* @param
* The type this Promise will produce as result
*/
public interface Promise {
/**
* Creates an instance of Promise.
* E.g. Promise<String> p = Promise.apply();
*
* @param
* The type this Promise will produce as result
* @return The Promise instance
* @since 1.2
*/
public static Promise apply() {
return new PromiseImpl();
}
/**
* Get a {@link Future} that will hold the value once this Promise is completed.
* Each {@link Promise} is connected to a single {@link Future}, invoking this method multiple times will always return the same {@link Future} instance.
*
* @return A Future that will hold the value once this Promise is completed.
* @since 1.2
*/
Future future();
/**
* Check if the {@link Promise} have been completed, with a value or an exception.
*
* @return true
if the {@link Promise} has been completed. false
otherwise.
* @since 1.2
*/
boolean isCompleted();
/**
* Completes the {@link Promise} with either a {@link Success} or a {@link Failure}.
*
* @param result
* The result to complete with.
* @throws IllegalStateException
* Thrown if the Promise is already completed.
* @since 1.3
*/
void complete(Try result);
/**
* Completes the {@link Promise} with the value from the provided {@link Future} once that is completed.
*
* @param future
* The future whose value will complete this Promise
* @throws IllegalStateException
* Thrown if the Promise is already completed.
* @since 1.3
*/
void completeWith(Future future);
/**
* Completes the {@link Promise} with a value.
*
* @param result
* The value to complete with.
* @throws IllegalStateException
* Thrown if the Promise is already completed.
* @since 1.2
*/
void success(T result);
/**
* Completes the {@link Promise} with an exception.
*
* @param throwable
* The Throwable to complete with.
* @throws IllegalStateException
* Thrown if the Promise is already completed.
* @since 1.2
*/
void failure(Throwable throwable);
/**
* Tries to complete the {@link Promise} with either a {@link Success} or a {@link Failure}.
* Contrary to the {@link #complete(Try)} method this does not throw an exception in case the Promise is already completed.
*
* @param result
* The result to complete with.
* @return true
if the Promise was not completed before, false
otherwise
* @since 1.3
*/
boolean tryComplete(Try result);
/**
* Tries to complete this {@link Promise} with the value from the provided {@link Future} once that is completed.
* Contrary to the {@link #complete(Try)} method this does not throw an exception in case the Promise is already completed.
*
* @param future
* The future whose value will complete this Promise
* @return true
if the Promise was not completed before, false
otherwise
* @since 1.3
*/
boolean tryCompleteWith(Future future);
/**
* Tries to complete the {@link Promise} with a value.
* Contrary to the {@link #success(Object)} method this does not throw an exception in case the Promise is already completed.
*
* @param result
* The value to complete with.
* @return true
if the Promise was not completed before, false
otherwise
* @since 1.3
*/
boolean trySuccess(T result);
/**
* Tries to complete the {@link Promise} with an exception.
* Contrary to the {@link #failure(Throwable)} method this does not throw an exception in case the Promise is already completed.
*
* @param throwable
* The Throwable to complete with.
* @return true
if the Promise was not completed before, false
otherwise
* @since 1.3
*/
boolean tryFailure(Throwable throwable);
}