001/*
002 * (C) Copyright 2012-2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.work.api;
020
021import java.util.List;
022import java.util.concurrent.TimeUnit;
023
024import org.nuxeo.ecm.core.work.api.Work.State;
025
026/**
027 * A {@link WorkManager} executes {@link Work} instances asynchronously.
028 * <p>
029 * A {@link Work} can be scheduled by calling {@link #schedule}.
030 * <p>
031 * Work is executed in a thread pool and a work queue that depends on the work's category.
032 *
033 * @since 5.6
034 */
035public interface WorkManager {
036
037    /**
038     * The scheduling policy to use when adding a work instance using {@link #schedule(Work, Scheduling)}.
039     */
040    enum Scheduling {
041        /**
042         * Always schedule the work.
043         */
044        ENQUEUE,
045        /**
046         * Any other scheduled work equals to this one is removed from scheduling and canceled first, before this work
047         * is scheduled.
048         */
049        CANCEL_SCHEDULED,
050        /**
051         * If there is a scheduled work equals to this one, then don't schedule the work.
052         */
053        IF_NOT_SCHEDULED(State.SCHEDULED),
054        /**
055         * If there is a running or scheduled work equals to this one, then don't schedule the work.
056         */
057        IF_NOT_RUNNING_OR_SCHEDULED;
058
059        public final State state;
060
061        Scheduling() {
062            state = null;
063        }
064
065        Scheduling(State state) {
066            this.state = state;
067        }
068    }
069
070    /**
071     * Schedules work for execution at a later time.
072     * <p>
073     * This method is identical to {@link #schedule(Work, boolean)} with {@code afterCommit = false}.
074     *
075     * @param work the work to execute
076     */
077    void schedule(Work work);
078
079    /**
080     * Schedules work for execution at a later time, after the current transaction (if any) has committed.
081     *
082     * @param work the work to execute
083     * @param afterCommit if {@code true} and the work is scheduled, it will only be run after the current transaction
084     *            (if any) has committed
085     */
086    void schedule(Work work, boolean afterCommit);
087
088    /**
089     * Schedules work for execution at a later time, with a specific {@linkplain Scheduling scheduling} policy.
090     * <p>
091     * This method is identical to {@link #schedule(Work, Scheduling, boolean)} with {@code afterCommit = false}.
092     *
093     * @param work the work to execute
094     * @param scheduling the scheduling policy
095     * @see #schedule(Work)
096     */
097    void schedule(Work work, Scheduling scheduling);
098
099    /**
100     * Schedules work for execution at a later time, with a specific {@linkplain Scheduling scheduling} policy.
101     *
102     * @param work the work to execute
103     * @param scheduling the scheduling policy
104     * @param afterCommit if {@code true} and the work is scheduled, it will only be run after the current transaction
105     *            (if any) has committed
106     * @see #schedule(Work)
107     */
108    void schedule(Work work, Scheduling scheduling, boolean afterCommit);
109
110    /** Admin API **/
111    /**
112     * Lists the ids of the existing work queues.
113     *
114     * @return the list of queue ids
115     */
116    List<String> getWorkQueueIds();
117
118    /**
119     * Gets the queue id used for a given work category.
120     *
121     * @param category the category
122     * @return the queue id
123     */
124    String getCategoryQueueId(String category);
125
126    /**
127     * Gets the work queue descriptor for a given queue id.
128     *
129     * @param queueId the queue id
130     * @return the work queue descriptor, or {@code null}
131     */
132    WorkQueueDescriptor getWorkQueueDescriptor(String queueId);
133
134    /**
135     * Is processing enabled for at least one queue
136     *
137     * @since 8.3
138     */
139    boolean isProcessingEnabled();
140
141    /**
142     * Set processing for all queues
143     *
144     * @since 8.3
145     */
146
147    void enableProcessing(boolean value);
148
149    /**
150     * Is processing enabled for a given queue id.
151     *
152     * @since 8.3
153     */
154    boolean isProcessingEnabled(String queueId);
155
156    /**
157     * Set processing for a given queue id.
158     *
159     * @since 8.3
160     */
161    void enableProcessing(String queueId, boolean value);
162
163    /**
164     * Is queuing enabled for a given queue id.
165     *
166     * @since 8.3
167     */
168    boolean isQueuingEnabled(String queueId);
169
170    /**
171     * Starts up this {@link WorkManager} and attempts to resume work previously suspended and saved at
172     * {@link #shutdown} time.
173     */
174    void init();
175
176    /**
177     * Shuts down a work queue and attempts to suspend and save the running and scheduled work instances.
178     *
179     * @param queueId the queue id
180     * @param timeout the time to wait
181     * @param unit the timeout unit
182     * @return {@code true} if shutdown is done, {@code false} if there are still some threads executing after the
183     *         timeout
184     */
185    boolean shutdownQueue(String queueId, long timeout, TimeUnit unit) throws InterruptedException;
186
187    /**
188     * Shuts down this {@link WorkManager} and attempts to suspend and save the running and scheduled work instances.
189     *
190     * @param timeout the time to wait
191     * @param unit the timeout unit
192     * @return {@code true} if shutdown is done, {@code false} if there are still some threads executing after the
193     *         timeout
194     */
195    boolean shutdown(long timeout, TimeUnit unit) throws InterruptedException;
196
197    /**
198     * Gets the number of work instances in a given queue in a defined state.
199     * <p>
200     *
201     * @param queueId the queue id
202     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
203     *            RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed (
204     *            {@link State#SCHEDULED SCHEDULED} or {@link State#RUNNING RUNNING})
205     * @return the number of work instances in the given state
206     * @since 5.8
207     * @deprecated since 5.8,
208     */
209    @Deprecated
210    int getQueueSize(String queueId, State state);
211
212    /**
213     * Gets the metrics for the {@code queueId}
214     *
215     * @since 8.3
216     */
217    WorkQueueMetrics getMetrics(String queueId);
218
219    /**
220     * Waits for completion of work in a given queue.
221     *
222     * @param queueId the queue id
223     * @param timeout the time to wait
224     * @param unit the timeout unit
225     * @return {@code true} if all work completed in the queue, or {@code false} if there is still some non-completed
226     *         work after the timeout
227     */
228    boolean awaitCompletion(String queueId, long timeout, TimeUnit unit) throws InterruptedException;
229
230    /**
231     * Waits for completion of all work.
232     *
233     * @param timeout the time to wait
234     * @param unit the timeout unit
235     * @return {@code true} if all work completed, or {@code false} if there is still some non-completed work after the
236     *         timeout
237     */
238    boolean awaitCompletion(long timeout, TimeUnit unit) throws InterruptedException;
239
240    /**
241     * @return {@code true} if active
242     * @see org.nuxeo.runtime.model.DefaultComponent#applicationStarted(org.nuxeo.runtime.model.ComponentContext)
243     * @see #init()
244     * @see #shutdown(long, TimeUnit)
245     * @since 6.0
246     */
247    boolean isStarted();
248
249    /** Works lookup API **/
250    /**
251     * Gets the state in which a work instance is.
252     * <p>
253     * This can be {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING RUNNING}, or null.
254     *
255     * @param workId the id of the work to find
256     * @return the work state, or {@code null} if not found
257     * @since 5.8
258     */
259    @Deprecated
260    State getWorkState(String workId);
261
262    /**
263     * Finds a work instance.
264     *
265     * @param workId the id of the work to find
266     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
267     *            RUNNING}, or {@code null} for non-completed
268     * @return the found work instance, or {@code null} if not found
269     * @since 7.3
270     */
271    Work find(String workId, State state);
272
273    /**
274     * Lists the work instances in a given queue in a defined state.
275     *
276     * @param queueId the queue id
277     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
278     *            RUNNING}, or {@code null} for non-completed
279     * @return the list of work instances in the given state
280     */
281    List<Work> listWork(String queueId, State state);
282
283    /**
284     * Lists the work ids in a given queue in a defined state.
285     *
286     * @param queueId the queue id
287     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
288     *            RUNNING}, or {@code null} for non-completed
289     * @return the list of work ids in the given state
290     * @since 5.8
291     */
292    List<String> listWorkIds(String queueId, State state);
293
294}