1 24 25 package org.objectweb.cjdbc.controller.connection; 26 27 import java.sql.Connection ; 28 import java.util.NoSuchElementException ; 29 30 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException; 31 import org.objectweb.cjdbc.common.i18n.Translate; 32 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 33 34 44 public class RandomWaitPoolConnectionManager 45 extends AbstractPoolConnectionManager 46 { 47 48 private int timeout; 49 50 66 public RandomWaitPoolConnectionManager(String backendUrl, String backendName, 67 String login, String password, String driverPath, String driverClassName, 68 int poolSize, int timeout) 69 { 70 super(backendUrl, backendName, login, password, driverPath, 71 driverClassName, poolSize); 72 this.timeout = timeout * 1000; 73 } 74 75 78 protected Object clone() throws CloneNotSupportedException 79 { 80 return new RandomWaitPoolConnectionManager(backendUrl, backendName, rLogin, 81 rPassword, driverPath, driverClassName, poolSize, timeout); 82 } 83 84 89 public int getTimeout() 90 { 91 return timeout; 92 } 93 94 105 public synchronized Connection getConnection() 106 throws UnreachableBackendException 107 { 108 if (!initialized) 109 { 110 logger 111 .error("Requesting a connection from a non-initialized connection manager"); 112 return null; 113 } 114 115 long lTimeout = timeout; 116 117 while (freeConnections.isEmpty()) 125 { 126 try 128 { 129 if (lTimeout > 0) 130 { 131 long start = System.currentTimeMillis(); 132 this.wait(timeout); 134 long end = System.currentTimeMillis(); 135 lTimeout -= end - start; 136 if (lTimeout <= 0) 137 { 138 if (activeConnections.size() == 0) 139 { logger 142 .error("Backend " + backendName + " is no more accessible."); 143 throw new UnreachableBackendException(); 144 } 145 if (logger.isWarnEnabled()) 146 logger.warn("Timeout expired for connection on backend '" 147 + backendName 148 + "', consider increasing pool size (current size is " 149 + poolSize + ") or timeout (current timeout is " 150 + (timeout / 1000) + " seconds)"); 151 return null; 152 } 153 } 154 else 155 this.wait(); 156 } 157 catch (InterruptedException e) 158 { 159 logger 160 .error("Wait on freeConnections interrupted in RandomWaitPoolConnectionManager: " 161 + e); 162 return null; 163 } 164 } 165 166 try 168 { 169 Connection c = (Connection ) freeConnections.removeLast(); 170 activeConnections.add(c); 171 return c; 172 } 173 catch (NoSuchElementException e) 174 { 175 int missing = poolSize 176 - (activeConnections.size() + freeConnections.size()); 177 if (missing > 0) 178 { logger 180 .info("Trying to reallocate " + missing + " missing connections."); 181 Connection connectionToBeReturned = null; 182 while (missing > 0) 183 { 184 Connection c = getConnectionFromDriver(); 185 if (c == null) 186 { 187 if (missing == poolSize) 188 { 189 String msg = Translate.get("loadbalancer.backend.unreacheable", 190 backendName); 191 logger.error(msg); 192 throw new UnreachableBackendException(msg); 193 } 194 logger.warn("Unable to re-allocate " + missing 195 + " missing connections."); 196 break; 197 } 198 else 199 { 200 if (connectionToBeReturned == null) 201 connectionToBeReturned = c; 202 else 203 freeConnections.addLast(c); 204 } 205 missing--; 206 } 207 return connectionToBeReturned; 208 } 209 if (logger.isErrorEnabled()) 210 logger.error("Failed to get a connection on backend '" + backendName 211 + "' whereas an idle connection was expected"); 212 return null; 213 } 214 } 215 216 219 public synchronized void releaseConnection(Connection c) 220 { 221 if (!initialized) 222 return; 224 if (activeConnections.remove(c)) 225 { 226 freeConnections.addLast(c); 227 this.notify(); 228 } 229 else 230 logger.error("Failed to release connection " + c 231 + " (not found in active pool)"); 232 } 233 234 237 public synchronized void deleteConnection(Connection c) 238 { 239 if (!initialized) 240 return; 242 if (activeConnections.remove(c)) 243 { 244 Connection newConnection = getConnectionFromDriver(); 245 if (newConnection == null) 246 { 247 if (logger.isDebugEnabled()) 248 logger.error("Bad connection " + c 249 + " has been removed but cannot be replaced."); 250 } 251 else 252 { 253 freeConnections.addLast(newConnection); 254 this.notify(); 255 if (logger.isDebugEnabled()) 256 logger.debug("Bad connection " + c 257 + " has been replaced by a new connection."); 258 } 259 } 260 else 261 logger.error("Failed to release connection " + c 262 + " (not found in active pool)"); 263 } 264 265 268 public String getXmlImpl() 269 { 270 StringBuffer info = new StringBuffer (); 271 info.append("<" + DatabasesXmlTags.ELT_RandomWaitPoolConnectionManager 272 + " " + DatabasesXmlTags.ATT_poolSize + "=\"" + poolSize + "\" " 273 + DatabasesXmlTags.ATT_timeout + "=\"" + timeout / 1000 + "\"/>"); 274 return info.toString(); 275 } 276 277 } 278 | Popular Tags |