001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package javax.util.concurrent;
018    
019    import java.util.Date;
020    import java.util.concurrent.Future;
021    
022    /**
023     * Triggers allow application developers to plug in rules
024     * for when and how often a task should run.
025     * The trigger can be as simple as a single, absolute date-time or can include
026     * Java™ EE business calendar logic.
027     *
028     * A Trigger implementation is created by the application developer
029     * (or may be supplied to the application externally) and is registered
030     * with a task when it is submitted to a {@link javax.util.concurrent.ManagedScheduledExecutorService}
031     * using any of the <code>schedule</code> methods.
032     *
033     * Each method will run with the same context in which the task runs.
034     * The Trigger becomes a Contextual Task.<p>
035     *
036     * Each Trigger instance will be invoked within the same process in which it was registered.<p>
037     *
038     * Example:<pre>
039     *   &#47;**
040     *    * A trigger that only returns a single date.
041     *    *&#47;
042     *    public class SingleDateTrigger implements Trigger {
043     *        private Date fireTime;
044     *
045     *        public TriggerSingleDate(Date newDate) {
046     *            fireTime = newDate;
047     *        }
048     *
049     *        public Date getNextRunTime(
050     *           Future lastFuture, Date baseTime, Date lastActualRunTime,
051     *           Date lastScheduledRunTime, Date lastCompleteTime) {
052     *
053     *           if(baseTime.after(fireTime)) {
054     *               return null;
055     *           }
056     *           return fireTime;
057     *        }
058     *
059     *        public boolean skipRun(Future lastFuture, Date scheduledRunTime) {
060     *            return scheduledRunTime.after(fireTime);
061     *        }
062     *    }
063     *
064     *   &#47;**
065     *    * A fixed-rate trigger that will skip any runs if
066     *    * the latencyAllowance threshold is exceeded (the task
067     *    * ran too late).
068     *    *&#47;
069     *    public class TriggerFixedRateLatencySensitive implements Trigger {
070     *        private Date startTime;
071     *        private long delta;
072     *        private long latencyAllowance;
073     *
074     *        public TriggerFixedRateLatencySensitive(Date startTime, long delta, long latencyAllowance) {
075     *            this.startTime = startTime;
076     *            this.delta = delta;
077     *            this.latencyAllowance = latencyAllowance;
078     *        }
079     *
080     *        public Date getNextRunTime(Future lastFuture, Date baseTime, Date lastActualRunTime, Date lastScheduledRunTime, Date lastCompleteTime) {
081     *            if(lastActualRunTime==null) {
082     *                return startTime;
083     *            }
084     *            return new Date(lastScheduledRunTime.getTime() + delta);
085     *        }
086     *
087     *        public boolean skipRun(Future lastFuture, Date scheduledRunTime) {
088     *            return System.currentTimeMillis() - scheduledRunTime.getTime() > latencyAllowance;
089     *        }
090     *    }
091     *
092     * </pre>
093     *
094     */
095    public interface Trigger {
096    
097        /**
098         * Retrieve the next time that the task should run after.
099         *
100         * @param lastFuture the state of the Future after the last run.
101         *        This value will be null if the task has not yet run.
102         * @param submitTime the time in which the task was originally submitted.
103         * @param lastActualRunTime the time in which the last task actually ran.
104         *        This value will be null if the task has not yet run.
105         * @param lastScheduledRunTime the time in which the last task was scheduled to run.
106         *        This value will be null if the task has not yet run.
107         * @param lastCompleteTime the time in which the last task completed.
108         *        This value will be null if the task has not yet run.
109         * @return the date/time in which the next task iteration should execute on or after.
110         */
111        Date getNextRunTime(Future<?> lastFuture, Date submitTime, Date lastActualRunTime, Date lastScheduledRunTime, Date lastCompleteTime);
112    
113        /**
114         * Return true if this run instance should be skipped.<p>
115         *
116         * This is useful if the task shouldn't run because it is late or if the task is
117         * paused or suspended.<p>
118         *
119         * Once this task is skipped, the state of it's Future's result will throw a {@link SkippedException}.
120         * Unchecked exceptions will be wrapped in a SkippedException.
121         *
122         * @param scheduledRunTime the date/time that the task was originally scheduled to run.
123         *
124         * @return true if the task should be skipped and rescheduled.
125         */
126        boolean skipRun(Future<?> lastFuture, Date scheduledRunTime);
127    }