001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.api;
028 import org.opends.messages.Message;
029
030
031
032 import org.opends.server.admin.std.server.WorkQueueCfg;
033 import org.opends.server.config.ConfigException;
034 import org.opends.server.types.AbstractOperation;
035 import org.opends.server.types.DirectoryException;
036 import org.opends.server.types.InitializationException;
037
038
039
040 /**
041 * This class defines the structure and methods that must be
042 * implemented by a Directory Server work queue. The work queue is
043 * the component of the server that accepts requests from connection
044 * handlers and ensures that they are properly processed. The manner
045 * in which the work queue is able to accomplish this may vary between
046 * implementations, but in general it is assumed that one or more
047 * worker threads will be associated with the queue and may be used to
048 * process requests in parallel.
049 *
050 * @param <T> The type of configuration handled by this work queue.
051 */
052 @org.opends.server.types.PublicAPI(
053 stability=org.opends.server.types.StabilityLevel.VOLATILE,
054 mayInstantiate=false,
055 mayExtend=true,
056 mayInvoke=true)
057 public abstract class WorkQueue<T extends WorkQueueCfg>
058 {
059 /**
060 * Initializes this work queue based on the information in the
061 * provided configuration entry.
062 *
063 * @param configuration The configuration to use to initialize
064 * the work queue.
065 *
066 * @throws ConfigException If the provided configuration entry
067 * does not have a valid work queue
068 * configuration.
069 *
070 * @throws InitializationException If a problem occurs during
071 * initialization that is not
072 * related to the server
073 * configuration.
074 */
075 public abstract void initializeWorkQueue(T configuration)
076 throws ConfigException, InitializationException;
077
078
079
080 /**
081 * Performs any necessary finalization for this work queue,
082 * including ensuring that all active operations are interrupted or
083 * will be allowed to complete, and that all pending operations will
084 * be cancelled.
085 *
086 * @param reason The human-readable reason that the work queue is
087 * being shut down.
088 */
089 public abstract void finalizeWorkQueue(Message reason);
090
091
092
093 /**
094 * Submits an operation to be processed in the server.
095 *
096 * @param operation The operation to be processed.
097 *
098 * @throws DirectoryException If the provided operation is not
099 * accepted for some reason (e.g., if
100 * the server is shutting down or
101 * already has too many pending
102 * requests in the queue).
103 */
104 public abstract void submitOperation(AbstractOperation operation)
105 throws DirectoryException;
106
107
108
109 /**
110 * Indicates whether the work queue is currently processing any
111 * requests. Note that this is a point-in-time determination, and
112 * if any component of the server wishes to depend on a quiescent
113 * state then it should use some external mechanism to ensure that
114 * no other requests are submitted to the queue.
115 *
116 * @return {@code true} if the work queue is currently idle, or
117 * {@code false} if it is being used to process one or more
118 * operations.
119 */
120 public abstract boolean isIdle();
121
122
123
124 /**
125 * Waits for the work queue to become idle before returning. Note
126 * that this is a point-in-time determination, and if any component
127 * of the server wishes to depend on a quiescent state then it
128 * should use some external mechanism to ensure that no other
129 * requests are submitted to the queue.
130 *
131 * @param timeLimit The maximum length of time in milliseconds
132 * that this method should wait for the queue to
133 * become idle before giving up. A time limit
134 * that is less than or equal to zero indicates
135 * that there should not be a time limit.
136 *
137 * @return {@code true} if the work queue is idle at the time that
138 * this method returns, or {@code false} if the wait time
139 * limit was reached before the server became idle.
140 */
141 public boolean waitUntilIdle(long timeLimit)
142 {
143 long stopWaitingTime;
144 if (timeLimit <= 0)
145 {
146 stopWaitingTime = Long.MAX_VALUE;
147 }
148 else
149 {
150 stopWaitingTime = System.currentTimeMillis() + timeLimit;
151 }
152
153 while (System.currentTimeMillis() < stopWaitingTime)
154 {
155 if (isIdle())
156 {
157 return true;
158 }
159
160 try
161 {
162 Thread.sleep(1);
163 } catch (InterruptedException ie) {}
164 }
165
166 return false;
167 }
168 }
169