1 23 24 package org.continuent.sequoia.controller.connection; 25 26 import java.sql.Connection ; 27 import java.util.NoSuchElementException ; 28 29 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 30 import org.continuent.sequoia.common.i18n.Translate; 31 import org.continuent.sequoia.common.xml.DatabasesXmlTags; 32 33 43 public class RandomWaitPoolConnectionManager 44 extends AbstractPoolConnectionManager 45 { 46 47 private int timeout; 48 49 65 public RandomWaitPoolConnectionManager(String backendUrl, String backendName, 66 String login, String password, String driverPath, String driverClassName, 67 int poolSize, int timeout) 68 { 69 super(backendUrl, backendName, login, password, driverPath, 70 driverClassName, poolSize); 71 this.timeout = timeout * 1000; 72 } 73 74 77 protected Object clone() throws CloneNotSupportedException 78 { 79 return new RandomWaitPoolConnectionManager(backendUrl, backendName, rLogin, 80 rPassword, driverPath, driverClassName, poolSize, timeout); 81 } 82 83 87 public AbstractConnectionManager clone(String rLogin, String rPassword) 88 { 89 return new RandomWaitPoolConnectionManager(backendUrl, backendName, rLogin, 90 rPassword, driverPath, driverClassName, poolSize, timeout); 91 } 92 93 98 public int getTimeout() 99 { 100 return timeout; 101 } 102 103 114 public synchronized PooledConnection getConnection() 115 throws UnreachableBackendException 116 { 117 if (!initialized) 118 { 119 logger 120 .error("Requesting a connection from a non-initialized connection manager"); 121 return null; 122 } 123 if (isShutdown) 124 { 125 return null; 126 } 127 long lTimeout = timeout; 128 129 while (freeConnections.isEmpty()) 137 { 138 try 140 { 141 if (lTimeout > 0) 142 { 143 long start = System.currentTimeMillis(); 144 this.wait(timeout); 146 long end = System.currentTimeMillis(); 147 lTimeout -= end - start; 148 if (lTimeout <= 0) 149 { 150 if (activeConnections.size() == 0) 151 { logger 154 .error("Backend " + backendName + " is no more accessible."); 155 throw new UnreachableBackendException(); 156 } 157 if (logger.isWarnEnabled()) 158 logger.warn("Timeout expired for connection on backend '" 159 + backendName 160 + "', consider increasing pool size (current size is " 161 + poolSize + ") or timeout (current timeout is " 162 + (timeout / 1000) + " seconds)"); 163 return null; 164 } 165 } 166 else 167 this.wait(); 168 } 169 catch (InterruptedException e) 170 { 171 logger 172 .error("Wait on freeConnections interrupted in RandomWaitPoolConnectionManager: " 173 + e); 174 return null; 175 } 176 } 177 if (isShutdown) 178 { 179 return null; 180 } 181 try 183 { 184 PooledConnection c = (PooledConnection) freeConnections.removeLast(); 185 activeConnections.add(c); 186 return c; 187 } 188 catch (NoSuchElementException e) 189 { 190 int missing = poolSize 191 - (activeConnections.size() + freeConnections.size()); 192 if (missing > 0) 193 { logger 195 .info("Trying to reallocate " + missing + " missing connections."); 196 PooledConnection connectionToBeReturned = null; 197 while (missing > 0) 198 { 199 Connection c = getConnectionFromDriver(); 200 if (c == null) 201 { 202 if (missing == poolSize) 203 { 204 String msg = Translate.get("loadbalancer.backend.unreacheable", 205 backendName); 206 logger.error(msg); 207 throw new UnreachableBackendException(msg); 208 } 209 logger.warn("Unable to re-allocate " + missing 210 + " missing connections."); 211 break; 212 } 213 else 214 { 215 if (connectionToBeReturned == null) 216 connectionToBeReturned = new PooledConnection(c); 217 else 218 freeConnections.addLast(new PooledConnection(c)); 219 } 220 missing--; 221 } 222 return connectionToBeReturned; 223 } 224 if (logger.isErrorEnabled()) 225 logger.error("Failed to get a connection on backend '" + backendName 226 + "' whereas an idle connection was expected"); 227 return null; 228 } 229 } 230 231 234 public synchronized void releaseConnection(PooledConnection c) 235 { 236 if (!initialized) 237 { 238 closeConnection(c); 239 return; } 241 242 if (activeConnections.remove(c)) 243 { 244 freeConnections.addLast(c); 245 this.notify(); 246 } 247 else 248 logger.error("Failed to release connection " + c 249 + " (not found in active pool)"); 250 } 251 252 255 public synchronized void deleteConnection(PooledConnection c) 256 { 257 closeConnection(c); 258 if (!initialized) 259 return; 261 if (activeConnections.remove(c)) 262 { 263 Connection newConnection = getConnectionFromDriver(); 264 if (newConnection == null) 265 { 266 if (logger.isDebugEnabled()) 267 logger.error("Bad connection " + c 268 + " has been removed but cannot be replaced."); 269 } 270 else 271 { 272 freeConnections.addLast(newConnection); 273 this.notify(); 274 if (logger.isDebugEnabled()) 275 logger.debug("Bad connection " + c 276 + " has been replaced by a new connection."); 277 } 278 } 279 else 280 logger.error("Failed to release connection " + c 281 + " (not found in active pool)"); 282 } 283 284 287 public String getXmlImpl() 288 { 289 StringBuffer info = new StringBuffer (); 290 info.append("<" + DatabasesXmlTags.ELT_RandomWaitPoolConnectionManager 291 + " " + DatabasesXmlTags.ATT_poolSize + "=\"" + poolSize + "\" " 292 + DatabasesXmlTags.ATT_timeout + "=\"" + timeout / 1000 + "\"/>"); 293 return info.toString(); 294 } 295 296 } 297 | Popular Tags |