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