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