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