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  * @since 1.5
64  * @author Doug Lea
65  * @param (V) The result type returned by this Future's {@code get} method
66  */
67 interface Future(V) {
68 
69     /**
70      * Attempts to cancel execution of this task.  This attempt will
71      * fail if the task has already completed, has already been cancelled,
72      * or could not be cancelled for some other reason. If successful,
73      * and this task has not started when {@code cancel} is called,
74      * this task should never run.  If the task has already started,
75      * then the {@code mayInterruptIfRunning} parameter determines
76      * whether the thread executing this task should be interrupted in
77      * an attempt to stop the task.
78      *
79      * <p>After this method returns, subsequent calls to {@link #isDone} will
80      * always return {@code true}.  Subsequent calls to {@link #isCancelled}
81      * will always return {@code true} if this method returned {@code true}.
82      *
83      * @param mayInterruptIfRunning {@code true} if the thread executing this
84      * task should be interrupted; otherwise, in-progress tasks are allowed
85      * to complete
86      * @return {@code false} if the task could not be cancelled,
87      * typically because it has already completed normally;
88      * {@code true} otherwise
89      */
90     bool cancel(bool mayInterruptIfRunning);
91 
92     /**
93      * Returns {@code true} if this task was cancelled before it completed
94      * normally.
95      *
96      * @return {@code true} if this task was cancelled before it completed
97      */
98     bool isCancelled();
99 
100     /**
101      * Returns {@code true} if this task completed.
102      *
103      * Completion may be due to normal termination, an exception, or
104      * cancellation -- in all of these cases, this method will return
105      * {@code true}.
106      *
107      * @return {@code true} if this task completed
108      */
109     bool isDone();
110 
111     /**
112      * Waits if necessary for the computation to complete, and then
113      * retrieves its result.
114      *
115      * @return the computed result
116      * @throws CancellationException if the computation was cancelled
117      * @throws ExecutionException if the computation threw an
118      * exception
119      * @throws InterruptedException if the current thread was interrupted
120      * while waiting
121      */
122     V get();
123 
124     /**
125      * Waits if necessary for at most the given time for the computation
126      * to complete, and then retrieves its result, if available.
127      *
128      * @param timeout the maximum time to wait
129      * @param unit the time unit of the timeout argument
130      * @return the computed result
131      * @throws CancellationException if the computation was cancelled
132      * @throws ExecutionException if the computation threw an
133      * exception
134      * @throws InterruptedException if the current thread was interrupted
135      * while waiting
136      * @throws TimeoutException if the wait timed out
137      */
138     V get(Duration timeout);
139 }
140 
141 
142 /**
143  * A {@link Future} that is {@link Runnable}. Successful execution of
144  * the {@code run} method causes completion of the {@code Future}
145  * and allows access to its results.
146  * @see FutureTask
147  * @see Executor
148  * @since 1.6
149  * @author Doug Lea
150  * @param (V) The result type returned by this Future's {@code get} method
151  */
152 interface RunnableFuture(V) : Runnable, Future!(V) {
153     /**
154      * Sets this Future to the result of its computation
155      * unless it has been cancelled.
156      */
157     void run();
158 }