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 }