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     * @return true if the implementation supports processing disabling
143     * @since 10.3
144     */
145    boolean supportsProcessingDisabling();
146
147    /**
148     * Set processing for all queues
149     *
150     * @since 8.3
151     */
152
153    void enableProcessing(boolean value);
154
155    /**
156     * Is processing enabled for a given queue id.
157     *
158     * @since 8.3
159     */
160    boolean isProcessingEnabled(String queueId);
161
162    /**
163     * Set processing for a given queue id.
164     *
165     * @since 8.3
166     */
167    void enableProcessing(String queueId, boolean value);
168
169    /**
170     * Is queuing enabled for a given queue id.
171     *
172     * @since 8.3
173     */
174    boolean isQueuingEnabled(String queueId);
175
176    /**
177     * Starts up this {@link WorkManager} and attempts to resume work previously suspended and saved at
178     * {@link #shutdown} time.
179     */
180    void init();
181
182    /**
183     * Shuts down a work queue and attempts to suspend and save the running and scheduled work instances.
184     *
185     * @param queueId the queue id
186     * @param timeout the time to wait
187     * @param unit the timeout unit
188     * @return {@code true} if shutdown is done, {@code false} if there are still some threads executing after the
189     *         timeout
190     */
191    boolean shutdownQueue(String queueId, long timeout, TimeUnit unit) throws InterruptedException;
192
193    /**
194     * Shuts down this {@link WorkManager} and attempts to suspend and save the running and scheduled work instances.
195     *
196     * @param timeout the time to wait
197     * @param unit the timeout unit
198     * @return {@code true} if shutdown is done, {@code false} if there are still some threads executing after the
199     *         timeout
200     */
201    boolean shutdown(long timeout, TimeUnit unit) throws InterruptedException;
202
203    /**
204     * Gets the number of work instances in a given queue in a defined state.
205     * <p>
206     *
207     * @param queueId the queue id
208     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
209     *            RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed (
210     *            {@link State#SCHEDULED SCHEDULED} or {@link State#RUNNING RUNNING})
211     * @return the number of work instances in the given state
212     * @since 5.8
213     * @deprecated since 5.8,
214     */
215    @Deprecated
216    int getQueueSize(String queueId, State state);
217
218    /**
219     * Gets the metrics for the {@code queueId}
220     *
221     * @since 8.3
222     */
223    WorkQueueMetrics getMetrics(String queueId);
224
225    /**
226     * Waits for completion of work in a given queue.
227     *
228     * @param queueId the queue id
229     * @param timeout the time to wait
230     * @param unit the timeout unit
231     * @return {@code true} if all work completed in the queue, or {@code false} if there is still some non-completed
232     *         work after the timeout
233     */
234    boolean awaitCompletion(String queueId, long timeout, TimeUnit unit) throws InterruptedException;
235
236    /**
237     * Waits for completion of all work.
238     *
239     * @param timeout the time to wait
240     * @param unit the timeout unit
241     * @return {@code true} if all work completed, or {@code false} if there is still some non-completed work after the
242     *         timeout
243     */
244    boolean awaitCompletion(long timeout, TimeUnit unit) throws InterruptedException;
245
246    /**
247     * @return {@code true} if active
248     * @see org.nuxeo.runtime.model.DefaultComponent#applicationStarted(org.nuxeo.runtime.model.ComponentContext)
249     * @see #init()
250     * @see #shutdown(long, TimeUnit)
251     * @since 6.0
252     */
253    boolean isStarted();
254
255    /** Works lookup API **/
256    /**
257     * Gets the state in which a work instance is.
258     * <p>
259     * This can be {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING RUNNING}, or null.
260     *
261     * @param workId the id of the work to find
262     * @return the work state, or {@code null} if not found
263     * @since 5.8
264     */
265    @Deprecated
266    State getWorkState(String workId);
267
268    /**
269     * Finds a work instance.
270     *
271     * @param workId the id of the work to find
272     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
273     *            RUNNING}, or {@code null} for non-completed
274     * @return the found work instance, or {@code null} if not found
275     * @since 7.3
276     * @deprecated since 10.2 not scalable
277     */
278    @Deprecated
279    Work find(String workId, State state);
280
281    /**
282     * Lists the work instances in a given queue in a defined state.
283     *
284     * @param queueId the queue id
285     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
286     *            RUNNING}, or {@code null} for non-completed
287     * @return the list of work instances in the given state
288     * @deprecated since 10.2 not scalable
289     */
290    @Deprecated
291    List<Work> listWork(String queueId, State state);
292
293    /**
294     * Lists the work ids in a given queue in a defined state.
295     *
296     * @param queueId the queue id
297     * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING
298     *            RUNNING}, or {@code null} for non-completed
299     * @return the list of work ids in the given state
300     * @since 5.8
301     * @deprecated since 10.2 not scalable
302     */
303    @Deprecated
304    List<String> listWorkIds(String queueId, State state);
305
306}