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.ScheduledExecutorService;
13 
14 import hunt.concurrency.ExecutorService;
15 import hunt.concurrency.Delayed;
16 
17 import hunt.util.Common;
18 import hunt.util.Runnable;
19 
20 import core.time;
21 
22 /**
23  * An {@link ExecutorService} that can schedule commands to run after a given
24  * delay, or to execute periodically.
25  *
26  * <p>The {@code schedule} methods create tasks with various delays
27  * and return a task object that can be used to cancel or check
28  * execution. The {@code scheduleAtFixedRate} and
29  * {@code scheduleWithFixedDelay} methods create and execute tasks
30  * that run periodically until cancelled.
31  *
32  * <p>Commands submitted using the {@link Executor#execute(Runnable)}
33  * and {@link ExecutorService} {@code submit} methods are scheduled
34  * with a requested delay of zero. Zero and negative delays (but not
35  * periods) are also allowed in {@code schedule} methods, and are
36  * treated as requests for immediate execution.
37  *
38  * <p>All {@code schedule} methods accept <em>relative</em> delays and
39  * periods as arguments, not absolute times or dates. It is a simple
40  * matter to transform an absolute time represented as a {@link
41  * java.util.Date} to the required form. For example, to schedule at
42  * a certain future {@code date}, you can use: {@code schedule(task,
43  * date.getTime() - System.currentTimeMillis(),
44  * TimeUnit.MILLISECONDS)}. Beware however that expiration of a
45  * relative delay need not coincide with the current {@code Date} at
46  * which the task is enabled due to network time synchronization
47  * protocols, clock drift, or other factors.
48  *
49  * <p>The {@link Executors} class provides convenient factory methods for
50  * the ScheduledExecutorService implementations provided in this package.
51  *
52  * <h3>Usage Example</h3>
53  *
54  * Here is a class with a method that sets up a ScheduledExecutorService
55  * to beep every ten seconds for an hour:
56  *
57  * <pre> {@code
58  * import static hunt.concurrency.TimeUnit.*;
59  * class BeeperControl {
60  *   private final ScheduledExecutorService scheduler =
61  *     Executors.newScheduledThreadPool(1);
62  *
63  *   public void beepForAnHour() {
64  *     Runnable beeper = () -> System.out.println("beep");
65  *     ScheduledFuture<?> beeperHandle =
66  *       scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
67  *     Runnable canceller = () -> beeperHandle.cancel(false);
68  *     scheduler.schedule(canceller, 1, HOURS);
69  *   }
70  * }}</pre>
71  *
72  * @author Doug Lea
73  */
74 interface ScheduledExecutorService : ExecutorService {
75 
76     /**
77      * Submits a one-shot task that becomes enabled after the given delay.
78      *
79      * @param command the task to execute
80      * @param delay the time from now to delay execution
81      * @param unit the time unit of the delay parameter
82      * @return a ScheduledFuture representing pending completion of
83      *         the task and whose {@code get()} method will return
84      *         {@code null} upon completion
85      * @throws RejectedExecutionException if the task cannot be
86      *         scheduled for execution
87      * @throws NullPointerException if command or unit is null
88      */
89     ScheduledFuture!void schedule(Runnable command, Duration delay);
90 
91     // /**
92     //  * Submits a value-returning one-shot task that becomes enabled
93     //  * after the given delay.
94     //  *
95     //  * @param callable the function to execute
96     //  * @param delay the time from now to delay execution
97     //  * @param unit the time unit of the delay parameter
98     //  * @param (V) the type of the callable's result
99     //  * @return a ScheduledFuture that can be used to extract result or cancel
100     //  * @throws RejectedExecutionException if the task cannot be
101     //  *         scheduled for execution
102     //  * @throws NullPointerException if callable or unit is null
103     //  */
104     // !(V) ScheduledFuture!(V) schedule(Callable!(V) callable, Duration delay);
105 
106     /**
107      * Submits a periodic action that becomes enabled first after the
108      * given initial delay, and subsequently with the given period;
109      * that is, executions will commence after
110      * {@code initialDelay}, then {@code initialDelay + period}, then
111      * {@code initialDelay + 2 * period}, and so on.
112      *
113      * <p>The sequence of task executions continues indefinitely until
114      * one of the following exceptional completions occur:
115      * <ul>
116      * <li>The task is {@linkplain Future#cancel explicitly cancelled}
117      * via the returned future.
118      * <li>The executor terminates, also resulting in task cancellation.
119      * <li>An execution of the task throws an exception.  In this case
120      * calling {@link Future#get() get} on the returned future will throw
121      * {@link ExecutionException}, holding the exception as its cause.
122      * </ul>
123      * Subsequent executions are suppressed.  Subsequent calls to
124      * {@link Future#isDone isDone()} on the returned future will
125      * return {@code true}.
126      *
127      * <p>If any execution of this task takes longer than its period, then
128      * subsequent executions may start late, but will not concurrently
129      * execute.
130      *
131      * @param command the task to execute
132      * @param initialDelay the time to delay first execution
133      * @param period the period between successive executions
134      * @param unit the time unit of the initialDelay and period parameters
135      * @return a ScheduledFuture representing pending completion of
136      *         the series of repeated tasks.  The future's {@link
137      *         Future#get() get()} method will never return normally,
138      *         and will throw an exception upon task cancellation or
139      *         abnormal termination of a task execution.
140      * @throws RejectedExecutionException if the task cannot be
141      *         scheduled for execution
142      * @throws NullPointerException if command or unit is null
143      * @throws IllegalArgumentException if period less than or equal to zero
144      */
145     ScheduledFuture!void scheduleAtFixedRate(Runnable command,
146                                                   Duration initialDelay,
147                                                   Duration period);
148 
149     /**
150      * Submits a periodic action that becomes enabled first after the
151      * given initial delay, and subsequently with the given delay
152      * between the termination of one execution and the commencement of
153      * the next.
154      *
155      * <p>The sequence of task executions continues indefinitely until
156      * one of the following exceptional completions occur:
157      * <ul>
158      * <li>The task is {@linkplain Future#cancel explicitly cancelled}
159      * via the returned future.
160      * <li>The executor terminates, also resulting in task cancellation.
161      * <li>An execution of the task throws an exception.  In this case
162      * calling {@link Future#get() get} on the returned future will throw
163      * {@link ExecutionException}, holding the exception as its cause.
164      * </ul>
165      * Subsequent executions are suppressed.  Subsequent calls to
166      * {@link Future#isDone isDone()} on the returned future will
167      * return {@code true}.
168      *
169      * @param command the task to execute
170      * @param initialDelay the time to delay first execution
171      * @param delay the delay between the termination of one
172      * execution and the commencement of the next
173      * @param unit the time unit of the initialDelay and delay parameters
174      * @return a ScheduledFuture representing pending completion of
175      *         the series of repeated tasks.  The future's {@link
176      *         Future#get() get()} method will never return normally,
177      *         and will throw an exception upon task cancellation or
178      *         abnormal termination of a task execution.
179      * @throws RejectedExecutionException if the task cannot be
180      *         scheduled for execution
181      * @throws NullPointerException if command or unit is null
182      * @throws IllegalArgumentException if delay less than or equal to zero
183      */
184     ScheduledFuture!void scheduleWithFixedDelay(Runnable command,
185                                                      Duration initialDelay,
186                                                      Duration delay);
187 
188 }