001/* 002 * (C) Copyright 2012-2014 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Florent Guillaume 016 */ 017package org.nuxeo.ecm.core.work.api; 018 019import java.util.List; 020import java.util.concurrent.TimeUnit; 021 022import org.nuxeo.ecm.core.work.api.Work.State; 023 024/** 025 * A {@link WorkManager} executes {@link Work} instances asynchronously. 026 * <p> 027 * A {@link Work} can be scheduled by calling {@link #schedule}. 028 * <p> 029 * Work is executed in a thread pool and a work queue that depends on the work's category. 030 * 031 * @since 5.6 032 */ 033public interface WorkManager { 034 035 /** 036 * The scheduling policy to use when adding a work instance using {@link #schedule(Work, Scheduling)}. 037 */ 038 enum Scheduling { 039 /** 040 * Always schedule the work. 041 */ 042 ENQUEUE, 043 /** 044 * Any other scheduled work equals to this one is removed from scheduling and canceled first, before this work 045 * is scheduled. 046 */ 047 CANCEL_SCHEDULED, 048 /** 049 * If there is a scheduled work equals to this one, then don't schedule the work. 050 */ 051 IF_NOT_SCHEDULED(State.SCHEDULED), 052 /** 053 * If there is a running work equals to this one, then don't schedule the work. 054 * 055 * @deprecated unused 056 */ 057 @Deprecated 058 IF_NOT_RUNNING(State.RUNNING), 059 /** 060 * If there is a running or scheduled work equals to this one, then don't schedule the work. 061 */ 062 IF_NOT_RUNNING_OR_SCHEDULED; 063 064 public final State state; 065 066 private Scheduling() { 067 state = null; 068 } 069 070 private Scheduling(State state) { 071 this.state = state; 072 } 073 } 074 075 /** 076 * Lists the ids of the existing work queues. 077 * 078 * @return the list of queue ids 079 */ 080 List<String> getWorkQueueIds(); 081 082 /** 083 * Gets the queue id used for a given work category. 084 * 085 * @param category the category 086 * @return the queue id 087 */ 088 String getCategoryQueueId(String category); 089 090 /** 091 * Gets the work queue descriptor for a given queue id. 092 * 093 * @param queueId the queue id 094 * @return the work queue descriptor, or {@code null} 095 */ 096 WorkQueueDescriptor getWorkQueueDescriptor(String queueId); 097 098 /** 099 * Starts up this {@link WorkManager} and attempts to resume work previously suspended and saved at 100 * {@link #shutdown} time. 101 */ 102 void init(); 103 104 /** 105 * Shuts down a work queue and attempts to suspend and save the running and scheduled work instances. 106 * 107 * @param queueId the queue id 108 * @param timeout the time to wait 109 * @param unit the timeout unit 110 * @return {@code true} if shutdown is done, {@code false} if there are still some threads executing after the 111 * timeout 112 */ 113 boolean shutdownQueue(String queueId, long timeout, TimeUnit unit) throws InterruptedException; 114 115 /** 116 * Shuts down this {@link WorkManager} and attempts to suspend and save the running and scheduled work instances. 117 * 118 * @param timeout the time to wait 119 * @param unit the timeout unit 120 * @return {@code true} if shutdown is done, {@code false} if there are still some threads executing after the 121 * timeout 122 */ 123 boolean shutdown(long timeout, TimeUnit unit) throws InterruptedException; 124 125 /** 126 * Schedules work for execution at a later time. 127 * <p> 128 * This method is identical to {@link #schedule(Work, boolean)} with {@code afterCommit = false}. 129 * 130 * @param work the work to execute 131 */ 132 void schedule(Work work); 133 134 /** 135 * Schedules work for execution at a later time, after the current transaction (if any) has committed. 136 * 137 * @param work the work to execute 138 * @param afterCommit if {@code true} and the work is scheduled, it will only be run after the current transaction 139 * (if any) has committed 140 */ 141 void schedule(Work work, boolean afterCommit); 142 143 /** 144 * Schedules work for execution at a later time, with a specific {@linkplain Scheduling scheduling} policy. 145 * <p> 146 * This method is identical to {@link #schedule(Work, Scheduling, boolean)} with {@code afterCommit = false}. 147 * 148 * @param work the work to execute 149 * @param scheduling the scheduling policy 150 * @see #schedule(Work) 151 */ 152 void schedule(Work work, Scheduling scheduling); 153 154 /** 155 * Schedules work for execution at a later time, with a specific {@linkplain Scheduling scheduling} policy. 156 * 157 * @param work the work to execute 158 * @param scheduling the scheduling policy 159 * @param afterCommit if {@code true} and the work is scheduled, it will only be run after the current transaction 160 * (if any) has committed 161 * @see #schedule(Work) 162 */ 163 void schedule(Work work, Scheduling scheduling, boolean afterCommit); 164 165 /** 166 * Finds a work instance. 167 * 168 * @param work the work to find 169 * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING 170 * RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed 171 * @param useEquals ignored, always uses work id equality 172 * @param pos ignored, pass null 173 * @return the found work instance, or {@code null} if not found 174 * @deprecated since 5.8, use {@link #getWorkState} instead 175 */ 176 @Deprecated 177 Work find(Work work, State state, boolean useEquals, int[] pos); 178 179 /** 180 * Finds a work instance. 181 * 182 * @param workId the id of the work to find 183 * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING 184 * RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed 185 * @return the found work instance, or {@code null} if not found 186 * @since 7.3 187 */ 188 Work find(String workId, State state); 189 190 /** 191 * Finds a work result. 192 * 193 * @param workId the id of the work to find the result 194 * @return the found work result, or {@code null} if there is no result or if work is not {@link State#COMPLETED 195 * COMPLETED} 196 * @since 7.4 197 */ 198 String findResult(String workId); 199 200 /** 201 * Gets the state in which a work instance is. 202 * <p> 203 * This can be {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING RUNNING}, {@link State#COMPLETED COMPLETED}, 204 * {@link State#CANCELED} or {@link State#FAILED}. 205 * 206 * @param workId the id of the work to find 207 * @return the work state, or {@code null} if not found 208 * @since 5.8 209 */ 210 State getWorkState(String workId); 211 212 /** 213 * Lists the work instances in a given queue in a defined state. 214 * 215 * @param queueId the queue id 216 * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING 217 * RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed 218 * @return the list of work instances in the given state 219 */ 220 List<Work> listWork(String queueId, State state); 221 222 /** 223 * Lists the work ids in a given queue in a defined state. 224 * 225 * @param queueId the queue id 226 * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING 227 * RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed 228 * @return the list of work ids in the given state 229 * @since 5.8 230 */ 231 List<String> listWorkIds(String queueId, State state); 232 233 /** 234 * Gets the number of work instances in a given queue in a defined state. 235 * <p> 236 * 237 * @param queueId the queue id 238 * @param state the state defining the state to look into, {@link State#SCHEDULED SCHEDULED}, {@link State#RUNNING 239 * RUNNING}, {@link State#COMPLETED COMPLETED}, or {@code null} for non-completed ( 240 * {@link State#SCHEDULED SCHEDULED} or {@link State#RUNNING RUNNING}) 241 * @return the number of work instances in the given state 242 * @since 5.8 243 */ 244 int getQueueSize(String queueId, State state); 245 246 /** 247 * Gets the size of the non-completed work (scheduled + running) for a give queue. 248 * 249 * @param queueId the queue id 250 * @return the number of non-completed work instances 251 * @deprecated since 5.8, use {@link #getQueueSize} with {@code null} state instead 252 */ 253 @Deprecated 254 int getNonCompletedWorkSize(String queueId); 255 256 /** 257 * Waits for completion of work in a given queue. 258 * 259 * @param queueId the queue id 260 * @param timeout the time to wait 261 * @param unit the timeout unit 262 * @return {@code true} if all work completed in the queue, or {@code false} if there is still some non-completed 263 * work after the timeout 264 */ 265 boolean awaitCompletion(String queueId, long timeout, TimeUnit unit) throws InterruptedException; 266 267 /** 268 * Waits for completion of all work. 269 * 270 * @param timeout the time to wait 271 * @param unit the timeout unit 272 * @return {@code true} if all work completed, or {@code false} if there is still some non-completed work after the 273 * timeout 274 */ 275 boolean awaitCompletion(long timeout, TimeUnit unit) throws InterruptedException; 276 277 /** 278 * Clears the list of completed work instances for a given queue. 279 * 280 * @param queueId the queue id 281 */ 282 void clearCompletedWork(String queueId); 283 284 /** 285 * Clears the list of completed work instances older than the given time. 286 * 287 * @param completionTime the completion time (milliseconds since epoch) before which completed work instances are 288 * cleared, or {@code 0} for all 289 */ 290 void clearCompletedWork(long completionTime); 291 292 /** 293 * Clears the list of completed work instances older than what's configured for each queue. 294 */ 295 void cleanup(); 296 297 /** 298 * @return {@code true} if active 299 * @see org.nuxeo.runtime.model.DefaultComponent#applicationStarted(org.nuxeo.runtime.model.ComponentContext) 300 * @see #init() 301 * @see #shutdown(long, TimeUnit) 302 * @since 6.0 303 */ 304 boolean isStarted(); 305 306}