1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 module hunt.pool.KeyedObjectPool; 18 19 import hunt.util.Common; 20 import hunt.Exceptions; 21 22 /** 23 * A "keyed" pooling interface. 24 * <p> 25 * A keyed pool maintains a pool of instances for each key value. 26 * </p> 27 * <p> 28 * Example of use: 29 * </p> 30 * <pre style="border:solid thin; padding: 1ex;" 31 * > Object obj = <code style="color:#00C">null</code>; 32 * Object key = <code style="color:#C00">"Key"</code>; 33 * 34 * <code style="color:#00C">try</code> { 35 * obj = pool.borrowObject(key); 36 * <code style="color:#0C0">//...use the object...</code> 37 * } <code style="color:#00C">catch</code>(Exception e) { 38 * <code style="color:#0C0">// invalidate the object</code> 39 * pool.invalidateObject(key, obj); 40 * <code style="color:#0C0">// do not return the object to the pool twice</code> 41 * obj = <code style="color:#00C">null</code>; 42 * } <code style="color:#00C">finally</code> { 43 * <code style="color:#0C0">// make sure the object is returned to the pool</code> 44 * <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) { 45 * pool.returnObject(key, obj); 46 * } 47 * }</pre> 48 * <p> 49 * {@link KeyedObjectPool} implementations <i>may</i> choose to store at most 50 * one instance per key value, or may choose to maintain a pool of instances 51 * for each key (essentially creating a {@link java.util.Map Map} of 52 * {@link ObjectPool pools}). 53 * </p> 54 * <p> 55 * See {@link hunt.pool.impl.GenericKeyedObjectPool 56 * GenericKeyedObjectPool} for an implementation. 57 * </p> 58 * 59 * @param <K> The type of keys maintained by this pool. 60 * @param <V> Type of element pooled in this pool. 61 * 62 * @see KeyedPooledObjectFactory 63 * @see ObjectPool 64 * @see hunt.pool.impl.GenericKeyedObjectPool GenericKeyedObjectPool 65 * 66 */ 67 interface KeyedObjectPool(K, V) : Closeable { 68 /** 69 * Obtains an instance from this pool for the specified <code>key</code>. 70 * <p> 71 * Instances returned from this method will have been either newly created 72 * with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be 73 * a previously idle object and have been activated with 74 * {@link KeyedPooledObjectFactory#activateObject activateObject} and then 75 * (optionally) validated with 76 * {@link KeyedPooledObjectFactory#validateObject validateObject}. 77 * </p> 78 * <p> 79 * By contract, clients <strong>must</strong> return the borrowed object 80 * using {@link #returnObject returnObject}, 81 * {@link #invalidateObject invalidateObject}, or a related method as 82 * defined in an implementation or sub-interface, using a <code>key</code> 83 * that is {@link Object#equals equivalent} to the one used to borrow the 84 * instance in the first place. 85 * </p> 86 * <p> 87 * The behaviour of this method when the pool has been exhausted is not 88 * strictly specified (although it may be specified by implementations). 89 * </p> 90 * 91 * @param key the key used to obtain the object 92 * 93 * @return an instance from this pool. 94 * 95 * @throws IllegalStateException 96 * after {@link #close close} has been called on this pool 97 * @throws Exception 98 * when {@link KeyedPooledObjectFactory#makeObject 99 * makeObject}exception 100 * @throws NoSuchElementException 101 * when the pool is exhausted and cannot or will not return 102 * another instance 103 */ 104 V borrowObject(K key); 105 106 /** 107 * Return an instance to the pool. By contract, <code>obj</code> 108 * <strong>must</strong> have been obtained using 109 * {@link #borrowObject borrowObject} or a related method as defined in an 110 * implementation or sub-interface using a <code>key</code> that is 111 * equivalent to the one used to borrow the instance in the first place. 112 * 113 * @param key the key used to obtain the object 114 * @param obj a {@link #borrowObject borrowed} instance to be returned. 115 * 116 * @throws IllegalStateException 117 * if an attempt is made to return an object to the pool that 118 * is in any state other than allocated (i.e. borrowed). 119 * Attempting to return an object more than once or attempting 120 * to return an object that was never borrowed from the pool 121 * will trigger this exception. 122 * 123 * @throws Exception if an instance cannot be returned to the pool 124 */ 125 void returnObject(K key, V obj); 126 127 /** 128 * Invalidates an object from the pool. 129 * <p> 130 * By contract, <code>obj</code> <strong>must</strong> have been obtained 131 * using {@link #borrowObject borrowObject} or a related method as defined 132 * in an implementation or sub-interface using a <code>key</code> that is 133 * equivalent to the one used to borrow the <code>Object</code> in the first 134 * place. 135 * </p> 136 * <p> 137 * This method should be used when an object that has been borrowed is 138 * determined (due to an exception or other problem) to be invalid. 139 * </p> 140 * 141 * @param key the key used to obtain the object 142 * @param obj a {@link #borrowObject borrowed} instance to be returned. 143 * 144 * @throws Exception if the instance cannot be invalidated 145 */ 146 void invalidateObject(K key, V obj); 147 148 /** 149 * Create an object using the {@link KeyedPooledObjectFactory factory} or 150 * other implementation dependent mechanism, passivate it, and then place it 151 * in the idle object pool. <code>addObject</code> is useful for 152 * "pre-loading" a pool with idle objects (Optional operation). 153 * 154 * @param key the key a new instance should be added to 155 * 156 * @throws Exception 157 * when {@link KeyedPooledObjectFactory#makeObject} fails. 158 * @throws IllegalStateException 159 * after {@link #close} has been called on this pool. 160 * @throws UnsupportedOperationException 161 * when this pool cannot add new idle objects. 162 */ 163 void addObject(K key); 164 165 /** 166 * Returns the number of instances corresponding to the given 167 * <code>key</code> currently idle in this pool. Returns a negative value if 168 * this information is not available. 169 * 170 * @param key the key to query 171 * @return the number of instances corresponding to the given 172 * <code>key</code> currently idle in this pool. 173 */ 174 int getNumIdle(K key); 175 176 /** 177 * Returns the number of instances currently borrowed from but not yet 178 * returned to the pool corresponding to the given <code>key</code>. 179 * Returns a negative value if this information is not available. 180 * 181 * @param key the key to query 182 * @return the number of instances currently borrowed from but not yet 183 * returned to the pool corresponding to the given <code>key</code>. 184 */ 185 int getNumActive(K key); 186 187 /** 188 * Returns the total number of instances currently idle in this pool. 189 * Returns a negative value if this information is not available. 190 * @return the total number of instances currently idle in this pool. 191 */ 192 int getNumIdle(); 193 194 /** 195 * Returns the total number of instances currently borrowed from this pool but 196 * not yet returned. Returns a negative value if this information is not 197 * available. 198 * @return the total number of instances currently borrowed from this pool but 199 * not yet returned. 200 */ 201 int getNumActive(); 202 203 /** 204 * Clears the pool, removing all pooled instances (optional operation). 205 * 206 * @throws UnsupportedOperationException when this implementation doesn't 207 * support the operation 208 * 209 * @throws Exception if the pool cannot be cleared 210 */ 211 void clear(); 212 213 /** 214 * Clears the specified pool, removing all pooled instances corresponding to 215 * the given <code>key</code> (optional operation). 216 * 217 * @param key the key to clear 218 * 219 * @throws UnsupportedOperationException when this implementation doesn't 220 * support the operation 221 * 222 * @throws Exception if the key cannot be cleared 223 */ 224 void clear(K key); 225 226 /** 227 * Close this pool, and free any resources associated with it. 228 * <p> 229 * Calling {@link #addObject addObject} or 230 * {@link #borrowObject borrowObject} after invoking this method on a pool 231 * will cause them to throw an {@link IllegalStateException}. 232 * </p> 233 * <p> 234 * Implementations should silently fail if not all resources can be freed. 235 * </p> 236 */ 237 override 238 void close(); 239 }