package com.github.atemerev.hollywood.future;
import com.github.atemerev.pms.listeners.HasMessageListeners;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
/**
* A <code>Promise</code> is generally a <code>Future</code> with support for appending continuations.
* A continuation is an action which will be executed at the moment the <code>Future</code> completes. This action
* can itself be a <code>Promise</code>, so they can be chained.
* <p/>
* <code>Promise<Void></code> form is also common -- it provides a convenient way to check for completion of
* some action (presumably running in a different thread) without caring for it's returned result.
* <p/>
* As an additional bonus, a <code>Promise</code> can accept message listeners. It will fire
* <code>CancelledEvent</code> when task is cancelled and <code>CompletedEvent</code> when task is done. During
* the execution progress, other messages can be fired and delivered to listeners.
*
* @author Alexander Temerev, Alexander Kuklev
* @version $Id$
*/
public interface Promise<T> extends Future<T>, HasMessageListeners {
/**
* Append a callable continuation to this <code>Promise</code>, which will be executed (in the promise's thread)
* as soon as the <code>Promise</code>'s execution is completed. The <code>Promise</code> for this continuation is
* returned, so it can be checked for it's own execution or appended with other continuations if necessary.
*
* @param continuation A continuation to append -- something implementing <code>Callable</code> interface.
* Normally it would be called a <em>closure</em>.
* @return A <code>Promise</code> for the continuation appended.
*/
public <W> Promise<W> append(Callable<W> continuation);
/**
* Append a runnable continuation to this <code>Promise</code>, which will be executed (in the promise's thread)
* as soon as the <code>Promise</code>'s execution is completed. The <code>Promise<Void></code> is
* returned, which can be checked for it's completion or appended with other continuations.
*
* @param continuation A continuation to append -- something implementing <code>Runnable</code> interface.
* @return A <code>Promise</code> for the continuation appended.
*/
public Promise<Void> append(Runnable continuation);
/**
* Append a callable continuation to this <code>Promise</code>, which will be executed by specified executor
* as soon as the <code>Promise</code>'s execution is completed. The <code>Promise</code> for this continuation is
* returned, so it can be checked for it's own execution or appended with other continuations if necessary.
*
* @param continuation A continuation to append -- something implementing <code>Callable</code> interface.
* Normally it would be called a <em>closure</em>.
* @param executor An executor to submit continuation to.
* @return A <code>Promise</code> for the continuation appended.
*/
public <W> Promise<W> append(Callable<W> continuation, Executor executor);
/**
* Append a runnable continuation to this <code>Promise</code>, which will be executed by specified executor
* as soon as the <code>Promise</code>'s execution is completed. The <code>Promise<Void></code> is
* returned, which can be checked for it's completion or appended with other continuations.
*
* @param continuation A continuation to append -- something implementing <code>Runnable</code> interface.
* @param executor An executor to submit continuation to.
* @return A <code>Promise</code> for the continuation appended.
*/
public Promise<Void> append(Runnable continuation, Executor executor);
/**
* Waits if necessary (blocking the current thread) for the computation to complete, and then
* retrieves its result.
*
* @return the computed result
* @throws java.util.concurrent.CancellationException
* if the computation was cancelled
* @throws RuntimeExecutionException if the computation threw an
* exception
*/
public T get();
/**
* Waits if necessary (blocking the current thread) for the timeout specified, and then, if the
* computation is complete, retrieves its result. Otherwise, throws TimeoutException.
*
* @param timeout Time to wait for task execution, in milliseconds.
* @return the computed result
* @throws java.util.concurrent.CancellationException
* if the computation was cancelled
* @throws RuntimeExecutionException if the computation threw an
* exception
* @throws java.util.concurrent.TimeoutException
* If timeout passed and calculation hasn't been completed yet.
*/
public T get(long timeout) throws TimeoutException;
/**
* Wait for this promise to complete and ignore the result (which can still be retrieved later). This method
* is just an alias to get(), but it's more convenient to use this form for <code>Promise<Void></code>
* tasks.
*/
public void join();
/**
* Wait for this promise to complete for the timeout specified and ignore the result. This method
* is just an alias to get(), but it's more convenient to use this form for <code>Promise<Void></code>
* tasks.
*
* @param timeout Time to wait for task execution, in milliseconds.
* @throws java.util.concurrent.TimeoutException
* If timeout passed and calculation hasn't been completed yet.
*/
public void join(long timeout) throws TimeoutException;
}