1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.concurrency.Future;
13 
14 import hunt.util.Common;
15 import core.time;
16 
17 /**
18  * A {@code Future} represents the result of an asynchronous
19  * computation.  Methods are provided to check if the computation is
20  * complete, to wait for its completion, and to retrieve the result of
21  * the computation.  The result can only be retrieved using method
22  * {@code get} when the computation has completed, blocking if
23  * necessary until it is ready.  Cancellation is performed by the
24  * {@code cancel} method.  Additional methods are provided to
25  * determine if the task completed normally or was cancelled. Once a
26  * computation has completed, the computation cannot be cancelled.
27  * If you would like to use a {@code Future} for the sake
28  * of cancellability but not provide a usable result, you can
29  * declare types of the form {@code Future<?>} and
30  * return {@code null} as a result of the underlying task.
31  *
32  * <p><b>Sample Usage</b> (Note that the following classes are all
33  * made-up.)
34  *
35  * <pre> {@code
36  * interface ArchiveSearcher { string search(string target); }
37  * class App {
38  *   ExecutorService executor = ...
39  *   ArchiveSearcher searcher = ...
40  *   void showSearch(string target) throws InterruptedException {
41  *     Callable!(string) task = () -> searcher.search(target);
42  *     Future!(string) future = executor.submit(task);
43  *     displayOtherThings(); // do other things while searching
44  *     try {
45  *       displayText(future.get()); // use future
46  *     } catch (ExecutionException ex) { cleanup(); return; }
47  *   }
48  * }}</pre>
49  *
50  * The {@link FutureTask} class is an implementation of {@code Future} that
51  * implements {@code Runnable}, and so may be executed by an {@code Executor}.
52  * For example, the above construction with {@code submit} could be replaced by:
53  * <pre> {@code
54  * FutureTask!(string) future = new FutureTask<>(task);
55  * executor.execute(future);}</pre>
56  *
57  * <p>Memory consistency effects: Actions taken by the asynchronous computation
58  * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
59  * actions following the corresponding {@code Future.get()} in another thread.
60  *
61  * @see FutureTask
62  * @see Executor
63  * @author Doug Lea
64  * @param (V) The result type returned by this Future's {@code get} method
65  */
66 interface Future(V) : IFuture {
67 
68     /**
69      * Waits if necessary for the computation to complete, and then
70      * retrieves its result.
71      *
72      * @return the computed result
73      * @throws CancellationException if the computation was cancelled
74      * @throws ExecutionException if the computation threw an
75      * exception
76      * @throws InterruptedException if the current thread was interrupted
77      * while waiting
78      */
79     V get();
80 
81     /**
82      * Waits if necessary for at most the given time for the computation
83      * to complete, and then retrieves its result, if available.
84      *
85      * @param timeout the maximum time to wait
86      * @param unit the time unit of the timeout argument
87      * @return the computed result
88      * @throws CancellationException if the computation was cancelled
89      * @throws ExecutionException if the computation threw an
90      * exception
91      * @throws InterruptedException if the current thread was interrupted
92      * while waiting
93      * @throws TimeoutException if the wait timed out
94      */
95     V get(Duration timeout);
96 }
97 
98 /**
99 */
100 interface IFuture {
101 
102     /**
103      * Attempts to cancel execution of this task.  This attempt will
104      * fail if the task has already completed, has already been cancelled,
105      * or could not be cancelled for some other reason. If successful,
106      * and this task has not started when {@code cancel} is called,
107      * this task should never run.  If the task has already started,
108      * then the {@code mayInterruptIfRunning} parameter determines
109      * whether the thread executing this task should be interrupted in
110      * an attempt to stop the task.
111      *
112      * <p>After this method returns, subsequent calls to {@link #isDone} will
113      * always return {@code true}.  Subsequent calls to {@link #isCancelled}
114      * will always return {@code true} if this method returned {@code true}.
115      *
116      * @param mayInterruptIfRunning {@code true} if the thread executing this
117      * task should be interrupted; otherwise, in-progress tasks are allowed
118      * to complete
119      * @return {@code false} if the task could not be cancelled,
120      * typically because it has already completed normally;
121      * {@code true} otherwise
122      */
123     bool cancel(bool mayInterruptIfRunning);
124 
125     /**
126      * Returns {@code true} if this task was cancelled before it completed
127      * normally.
128      *
129      * @return {@code true} if this task was cancelled before it completed
130      */
131     bool isCancelled();
132 
133     /**
134      * Returns {@code true} if this task completed.
135      *
136      * Completion may be due to normal termination, an exception, or
137      * cancellation -- in all of these cases, this method will return
138      * {@code true}.
139      *
140      * @return {@code true} if this task completed
141      */
142     bool isDone();
143 }
144 
145 
146 /**
147  * A {@link Future} that is {@link Runnable}. Successful execution of
148  * the {@code run} method causes completion of the {@code Future}
149  * and allows access to its results.
150  * @see FutureTask
151  * @see Executor
152  * @author Doug Lea
153  * @param (V) The result type returned by this Future's {@code get} method
154  */
155 interface RunnableFuture(V) : Runnable, Future!(V) {
156     /**
157      * Sets this Future to the result of its computation
158      * unless it has been cancelled.
159      */
160     void run();
161 }