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}