1 6 package org.logicalcobwebs.proxool; 7 8 import java.sql.Connection ; 9 import java.sql.SQLException ; 10 11 import org.apache.commons.logging.Log; 12 import org.apache.commons.logging.LogFactory; 13 14 21 public class Prototyper { 22 23 private ConnectionPool connectionPool; 24 25 private Log log = LogFactory.getLog(Prototyper.class); 26 27 private long connectionCount; 28 29 private final Object lock = new Integer (1); 30 31 private boolean sweepNeeded = true; 32 33 34 private long nextConnectionId = 1; 35 36 40 private boolean cancel; 41 42 46 private int connectionsBeingMade; 47 48 53 private ConnectionBuilderIF connectionBuilder = new DefaultConnectionBuilder(); 54 55 public Prototyper(ConnectionPool connectionPool) { 56 this.connectionPool = connectionPool; 57 this.log = connectionPool.getLog(); 58 } 59 60 protected boolean isSweepNeeded() { 61 return sweepNeeded; 62 } 63 64 protected void triggerSweep() { 65 sweepNeeded = true; 66 } 67 68 72 protected boolean sweep() { 73 74 boolean somethingDone = false; 75 try { 76 77 while (!cancel && connectionPool.isConnectionPoolUp()) { 78 79 83 String reason = null; 84 if (connectionCount >= getDefinition().getMaximumConnectionCount()) { 85 break; 87 } else if (connectionCount < getDefinition().getMinimumConnectionCount()) { 88 reason = "to achieve minimum of " + getDefinition().getMinimumConnectionCount(); 89 } else if (connectionPool.getAvailableConnectionCount() < getDefinition().getPrototypeCount()) { 90 reason = "to keep " + getDefinition().getPrototypeCount() + " available"; 91 } else { 92 break; 94 } 95 96 ProxyConnectionIF freshlyBuiltProxyConnection = null; 97 try { 98 if (!connectionPool.isConnectionPoolUp()) { 100 break; 101 } 102 freshlyBuiltProxyConnection = buildConnection(ConnectionInfoIF.STATUS_AVAILABLE, reason); 103 somethingDone = true; 104 } catch (Throwable e) { 105 log.error("Prototype", e); 106 break; 111 } 114 if (freshlyBuiltProxyConnection == null) { 115 } 118 } 119 } catch (Throwable t) { 120 log.error("Unexpected error", t); 121 } 122 123 return somethingDone; 124 } 125 126 134 protected ProxyConnection buildConnection(int status, String creator) throws SQLException , ProxoolException { 135 136 long id = 0; 137 synchronized (lock) { 138 139 if (connectionCount >= getDefinition().getMaximumConnectionCount()) { 141 throw new ProxoolException("ConnectionCount is " + connectionCount + ". Maximum connection count of " 142 + getDefinition().getMaximumConnectionCount() + " cannot be exceeded."); 143 } 144 145 checkSimultaneousBuildThrottle(); 146 147 connectionsBeingMade++; 148 connectionCount++; 149 id = nextConnectionId++; 150 } 151 152 153 ProxyConnection proxyConnection = null; 154 Connection realConnection = null; 155 156 try { 157 final ConnectionPoolDefinition definition = connectionPool.getDefinition(); 159 realConnection = connectionBuilder.buildConnection(definition); 160 161 163 String url = definition.getUrl(); 168 proxyConnection = new ProxyConnection(realConnection, id, url, connectionPool, definition, status); 169 170 try { 171 connectionPool.onBirth(realConnection); 172 } catch (Exception e) { 173 log.error("Problem during onBirth (ignored)", e); 174 } 175 176 boolean added = connectionPool.addProxyConnection(proxyConnection); 183 if (log.isDebugEnabled()) { 184 StringBuffer out = new StringBuffer (connectionPool.displayStatistics()); 185 out.append(" - Connection #"); 186 out.append(proxyConnection.getId()); 187 if (getDefinition().isVerbose()) { 188 out.append(" ("); 189 out.append(Integer.toHexString(proxyConnection.hashCode())); 190 out.append(")"); 191 } 192 out.append(" created "); 193 out.append(creator); 194 out.append(" = "); 195 out.append(ConnectionPool.getStatusDescription(proxyConnection.getStatus())); 196 if (getDefinition().isVerbose()) { 197 out.append(" -> "); 198 out.append(getDefinition().getUrl()); 199 out.append(" ("); 200 out.append(Integer.toHexString(proxyConnection.getConnection().hashCode())); 201 out.append(") by thread "); 202 out.append(Thread.currentThread().getName()); 203 } 204 log.debug(out); 205 if (!added) { 206 out = new StringBuffer (connectionPool.displayStatistics()); 207 out.append(" - Connection #"); 208 out.append(proxyConnection.getId()); 209 out.append(" has been discarded immediately because the definition it was built with is out of date"); 210 log.debug(out); 211 } 212 } 213 if (!added) { 214 proxyConnection.reallyClose(); 215 } 216 217 } catch (SQLException e) { 218 throw e; 220 } catch (RuntimeException e) { 221 if (log.isDebugEnabled()) { 222 log.debug("Prototyping problem", e); 223 } 224 throw e; 225 } catch (Throwable t) { 226 if (log.isDebugEnabled()) { 227 log.debug("Prototyping problem", t); 228 } 229 throw new ProxoolException("Unexpected prototyping problem", t); 230 } finally { 231 synchronized (lock) { 232 if (proxyConnection == null) { 233 connectionCount--; 236 } 237 connectionsBeingMade--; 238 } 239 240 } 241 242 return proxyConnection; 243 } 244 245 246 249 protected void connectionRemoved() { 250 connectionCount--; 251 } 252 253 257 protected void checkSimultaneousBuildThrottle() throws SQLException { 258 if (connectionsBeingMade > getDefinition().getSimultaneousBuildThrottle()) { 260 throw new SQLException ("We are already in the process of making " + connectionsBeingMade 261 + " connections and the number of simultaneous builds has been throttled to " 262 + getDefinition().getSimultaneousBuildThrottle()); 263 } 264 } 265 266 271 public long getConnectionCount() { 272 return connectionCount; 273 } 274 275 279 private ConnectionPoolDefinitionIF getDefinition() { 280 return connectionPool.getDefinition(); 281 } 282 283 286 public void cancel() { 287 cancel = true; 288 } 289 290 294 public String getAlias() { 295 return getDefinition().getAlias(); 296 } 297 298 307 public void quickRefuse() throws SQLException { 308 if (connectionCount >= getDefinition().getMaximumConnectionCount() && connectionPool.getAvailableConnectionCount() < 1) { 309 throw new SQLException ("Couldn't get connection because we are at maximum connection count (" + connectionCount + "/" + getDefinition().getMaximumConnectionCount() + ") and there are none available"); 310 } 311 } 312 } 313 314 315 | Popular Tags |