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 }