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.ExecutorService;
13 
14 import hunt.concurrency.Executor;
15 import hunt.collection.Collection;
16 import hunt.collection.List;
17 import hunt.Functions;
18 import hunt.util.Common;
19 
20 import std.datetime;
21 
22 /**
23  * An {@link Executor} that provides methods to manage termination and
24  * methods that can produce a {@link Future} for tracking progress of
25  * one or more asynchronous tasks.
26  *
27  * <p>An {@code ExecutorService} can be shut down, which will cause
28  * it to reject new tasks.  Two different methods are provided for
29  * shutting down an {@code ExecutorService}. The {@link #shutdown}
30  * method will allow previously submitted tasks to execute before
31  * terminating, while the {@link #shutdownNow} method prevents waiting
32  * tasks from starting and attempts to stop currently executing tasks.
33  * Upon termination, an executor has no tasks actively executing, no
34  * tasks awaiting execution, and no new tasks can be submitted.  An
35  * unused {@code ExecutorService} should be shut down to allow
36  * reclamation of its resources.
37  *
38  * <p>Method {@code submit} extends base method {@link
39  * Executor#execute(Runnable)} by creating and returning a {@link Future}
40  * that can be used to cancel execution and/or wait for completion.
41  * Methods {@code invokeAny} and {@code invokeAll} perform the most
42  * commonly useful forms of bulk execution, executing a collection of
43  * tasks and then waiting for at least one, or all, to
44  * complete. (Class {@link ExecutorCompletionService} can be used to
45  * write customized variants of these methods.)
46  *
47  * <p>The {@link Executors} class provides factory methods for the
48  * executor services provided in this package.
49  *
50  * <h3>Usage Examples</h3>
51  *
52  * Here is a sketch of a network service in which threads in a thread
53  * pool service incoming requests. It uses the preconfigured {@link
54  * Executors#newFixedThreadPool} factory method:
55  *
56  * <pre> {@code
57  * class NetworkService implements Runnable {
58  *   private final ServerSocket serverSocket;
59  *   private final ExecutorService pool;
60  *
61  *   public NetworkService(int port, int poolSize)
62  *       throws IOException {
63  *     serverSocket = new ServerSocket(port);
64  *     pool = Executors.newFixedThreadPool(poolSize);
65  *   }
66  *
67  *   public void run() { // run the service
68  *     try {
69  *       for (;;) {
70  *         pool.execute(new Handler(serverSocket.accept()));
71  *       }
72  *     } catch (IOException ex) {
73  *       pool.shutdown();
74  *     }
75  *   }
76  * }
77  *
78  * class Handler implements Runnable {
79  *   private final Socket socket;
80  *   Handler(Socket socket) { this.socket = socket; }
81  *   public void run() {
82  *     // read and service request on socket
83  *   }
84  * }}</pre>
85  *
86  * The following method shuts down an {@code ExecutorService} in two phases,
87  * first by calling {@code shutdown} to reject incoming tasks, and then
88  * calling {@code shutdownNow}, if necessary, to cancel any lingering tasks:
89  *
90  * <pre> {@code
91  * void shutdownAndAwaitTermination(ExecutorService pool) {
92  *   pool.shutdown(); // Disable new tasks from being submitted
93  *   try {
94  *     // Wait a while for existing tasks to terminate
95  *     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
96  *       pool.shutdownNow(); // Cancel currently executing tasks
97  *       // Wait a while for tasks to respond to being cancelled
98  *       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
99  *           System.err.println("Pool did not terminate");
100  *     }
101  *   } catch (InterruptedException ie) {
102  *     // (Re-)Cancel if current thread also interrupted
103  *     pool.shutdownNow();
104  *     // Preserve interrupt status
105  *     Thread.currentThread().interrupt();
106  *   }
107  * }}</pre>
108  *
109  * <p>Memory consistency effects: Actions in a thread prior to the
110  * submission of a {@code Runnable} or {@code Callable} task to an
111  * {@code ExecutorService}
112  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
113  * any actions taken by that task, which in turn <i>happen-before</i> the
114  * result is retrieved via {@code Future.get()}.
115  *
116  * @since 1.5
117  * @author Doug Lea
118  */
119 interface ExecutorService : Executor {
120 
121     /**
122      * Initiates an orderly shutdown in which previously submitted
123      * tasks are executed, but no new tasks will be accepted.
124      * Invocation has no additional effect if already shut down.
125      *
126      * <p>This method does not wait for previously submitted tasks to
127      * complete execution.  Use {@link #awaitTermination awaitTermination}
128      * to do that.
129      *
130      * @throws SecurityException if a security manager exists and
131      *         shutting down this ExecutorService may manipulate
132      *         threads that the caller is not permitted to modify
133      *         because it does not hold {@link
134      *         java.lang.RuntimePermission}{@code ("modifyThread")},
135      *         or the security manager's {@code checkAccess} method
136      *         denies access.
137      */
138     void shutdown();
139 
140     /**
141      * Attempts to stop all actively executing tasks, halts the
142      * processing of waiting tasks, and returns a list of the tasks
143      * that were awaiting execution.
144      *
145      * <p>This method does not wait for actively executing tasks to
146      * terminate.  Use {@link #awaitTermination awaitTermination} to
147      * do that.
148      *
149      * <p>There are no guarantees beyond best-effort attempts to stop
150      * processing actively executing tasks.  For example, typical
151      * implementations will cancel via {@link Thread#interrupt}, so any
152      * task that fails to respond to interrupts may never terminate.
153      *
154      * @return list of tasks that never commenced execution
155      * @throws SecurityException if a security manager exists and
156      *         shutting down this ExecutorService may manipulate
157      *         threads that the caller is not permitted to modify
158      *         because it does not hold {@link
159      *         java.lang.RuntimePermission}{@code ("modifyThread")},
160      *         or the security manager's {@code checkAccess} method
161      *         denies access.
162      */
163     List!(Runnable) shutdownNow();
164 
165     /**
166      * Returns {@code true} if this executor has been shut down.
167      *
168      * @return {@code true} if this executor has been shut down
169      */
170     bool isShutdown();
171 
172     /**
173      * Returns {@code true} if all tasks have completed following shut down.
174      * Note that {@code isTerminated} is never {@code true} unless
175      * either {@code shutdown} or {@code shutdownNow} was called first.
176      *
177      * @return {@code true} if all tasks have completed following shut down
178      */
179     bool isTerminated();
180 
181     /**
182      * Blocks until all tasks have completed execution after a shutdown
183      * request, or the timeout occurs, or the current thread is
184      * interrupted, whichever happens first.
185      *
186      * @param timeout the maximum time to wait
187      * @param unit the time unit of the timeout argument
188      * @return {@code true} if this executor terminated and
189      *         {@code false} if the timeout elapsed before termination
190      * @throws InterruptedException if interrupted while waiting
191      */
192     bool awaitTermination(Duration timeout);
193 
194     /**
195      * Submits a value-returning task for execution and returns a
196      * Future representing the pending results of the task. The
197      * Future's {@code get} method will return the task's result upon
198      * successful completion.
199      *
200      * <p>
201      * If you would like to immediately block waiting
202      * for a task, you can use constructions of the form
203      * {@code result = exec.submit(aCallable).get();}
204      *
205      * <p>Note: The {@link Executors} class includes a set of methods
206      * that can convert some other common closure-like objects,
207      * for example, {@link java.security.PrivilegedAction} to
208      * {@link Callable} form so they can be submitted.
209      *
210      * @param task the task to submit
211      * @param (T) the type of the task's result
212      * @return a Future representing pending completion of the task
213      * @throws RejectedExecutionException if the task cannot be
214      *         scheduled for execution
215      * @throws NullPointerException if the task is null
216      */
217     // Future!(T) submit(Callable!(T) task);
218 
219     /**
220      * Submits a Runnable task for execution and returns a Future
221      * representing that task. The Future's {@code get} method will
222      * return the given result upon successful completion.
223      *
224      * @param task the task to submit
225      * @param result the result to return
226      * @param (T) the type of the result
227      * @return a Future representing pending completion of the task
228      * @throws RejectedExecutionException if the task cannot be
229      *         scheduled for execution
230      * @throws NullPointerException if the task is null
231      */
232     // Future!(T) submit(Runnable task, T result);
233 
234     /**
235      * Submits a Runnable task for execution and returns a Future
236      * representing that task. The Future's {@code get} method will
237      * return {@code null} upon <em>successful</em> completion.
238      *
239      * @param task the task to submit
240      * @return a Future representing pending completion of the task
241      * @throws RejectedExecutionException if the task cannot be
242      *         scheduled for execution
243      * @throws NullPointerException if the task is null
244      */
245     // Future!(T) submit(Runnable task);
246 
247     /**
248      * Executes the given tasks, returning a list of Futures holding
249      * their status and results when all complete.
250      * {@link Future#isDone} is {@code true} for each
251      * element of the returned list.
252      * Note that a <em>completed</em> task could have
253      * terminated either normally or by throwing an exception.
254      * The results of this method are undefined if the given
255      * collection is modified while this operation is in progress.
256      *
257      * @param tasks the collection of tasks
258      * @param (T) the type of the values returned from the tasks
259      * @return a list of Futures representing the tasks, in the same
260      *         sequential order as produced by the iterator for the
261      *         given task list, each of which has completed
262      * @throws InterruptedException if interrupted while waiting, in
263      *         which case unfinished tasks are cancelled
264      * @throws NullPointerException if tasks or any of its elements are {@code null}
265      * @throws RejectedExecutionException if any task cannot be
266      *         scheduled for execution
267      */
268     // List!(Future!(T)) invokeAll(Collection!(Callable!(T)) tasks);
269 
270     /**
271      * Executes the given tasks, returning a list of Futures holding
272      * their status and results
273      * when all complete or the timeout expires, whichever happens first.
274      * {@link Future#isDone} is {@code true} for each
275      * element of the returned list.
276      * Upon return, tasks that have not completed are cancelled.
277      * Note that a <em>completed</em> task could have
278      * terminated either normally or by throwing an exception.
279      * The results of this method are undefined if the given
280      * collection is modified while this operation is in progress.
281      *
282      * @param tasks the collection of tasks
283      * @param timeout the maximum time to wait
284      * @param unit the time unit of the timeout argument
285      * @param (T) the type of the values returned from the tasks
286      * @return a list of Futures representing the tasks, in the same
287      *         sequential order as produced by the iterator for the
288      *         given task list. If the operation did not time out,
289      *         each task will have completed. If it did time out, some
290      *         of these tasks will not have completed.
291      * @throws InterruptedException if interrupted while waiting, in
292      *         which case unfinished tasks are cancelled
293      * @throws NullPointerException if tasks, any of its elements, or
294      *         unit are {@code null}
295      * @throws RejectedExecutionException if any task cannot be scheduled
296      *         for execution
297      */
298     // List!(Future!(T)) invokeAll(Collection!(Callable!(T)) tasks,
299     //                               Duration timeout);
300 
301     /**
302      * Executes the given tasks, returning the result
303      * of one that has completed successfully (i.e., without throwing
304      * an exception), if any do. Upon normal or exceptional return,
305      * tasks that have not completed are cancelled.
306      * The results of this method are undefined if the given
307      * collection is modified while this operation is in progress.
308      *
309      * @param tasks the collection of tasks
310      * @param (T) the type of the values returned from the tasks
311      * @return the result returned by one of the tasks
312      * @throws InterruptedException if interrupted while waiting
313      * @throws NullPointerException if tasks or any element task
314      *         subject to execution is {@code null}
315      * @throws IllegalArgumentException if tasks is empty
316      * @throws ExecutionException if no task successfully completes
317      * @throws RejectedExecutionException if tasks cannot be scheduled
318      *         for execution
319      */
320     // T invokeAny(Collection!(Callable!(T)) tasks);
321 
322     /**
323      * Executes the given tasks, returning the result
324      * of one that has completed successfully (i.e., without throwing
325      * an exception), if any do before the given timeout elapses.
326      * Upon normal or exceptional return, tasks that have not
327      * completed are cancelled.
328      * The results of this method are undefined if the given
329      * collection is modified while this operation is in progress.
330      *
331      * @param tasks the collection of tasks
332      * @param timeout the maximum time to wait
333      * @param unit the time unit of the timeout argument
334      * @param (T) the type of the values returned from the tasks
335      * @return the result returned by one of the tasks
336      * @throws InterruptedException if interrupted while waiting
337      * @throws NullPointerException if tasks, or unit, or any element
338      *         task subject to execution is {@code null}
339      * @throws TimeoutException if the given timeout elapses before
340      *         any task successfully completes
341      * @throws ExecutionException if no task successfully completes
342      * @throws RejectedExecutionException if tasks cannot be scheduled
343      *         for execution
344      */
345     // T invokeAny(Collection!(Callable!(T)) tasks,
346     //                 Duration timeout);
347 }