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 }