1 6 package org.logicalcobwebs.proxool; 7 8 import org.apache.commons.logging.Log; 9 import org.apache.commons.logging.LogFactory; 10 11 import java.sql.Connection ; 12 import java.sql.Statement ; 13 14 22 class HouseKeeper { 23 24 private static final Log LOG = LogFactory.getLog(HouseKeeper.class); 25 26 private ConnectionPool connectionPool; 27 28 private long timeLastSwept; 29 30 public HouseKeeper(ConnectionPool connectionPool) { 31 this.connectionPool = connectionPool; 32 } 33 34 protected void sweep() throws ProxoolException { 35 ConnectionPoolDefinitionIF definition = connectionPool.getDefinition(); 36 Log log = connectionPool.getLog(); 37 Statement testStatement = null; 38 try { 39 40 connectionPool.acquirePrimaryReadLock(); 41 42 Connection connection = null; 44 ProxyConnectionIF proxyConnection = null; 45 46 int recentlyStartedActiveConnectionCountTemp = 0; 47 48 int[] verifiedConnectionCountByState = new int[4]; 50 51 ProxyConnectionIF[] proxyConnections = connectionPool.getProxyConnections(); 52 for (int i = 0; i < proxyConnections.length; i++) { 53 proxyConnection = proxyConnections[i]; 54 connection = proxyConnection.getConnection(); 55 56 if (!connectionPool.isConnectionPoolUp()) { 57 break; 58 } 59 60 if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_AVAILABLE, ProxyConnectionIF.STATUS_OFFLINE)) { 64 try { 65 testStatement = connection.createStatement(); 66 67 if (proxyConnection.isReallyClosed()) { 69 proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_NULL); 70 connectionPool.removeProxyConnection(proxyConnection, "it appears to be closed", ConnectionPool.FORCE_EXPIRY, true); 71 } 72 73 String sql = definition.getHouseKeepingTestSql(); 74 if (sql != null && sql.length() > 0) { 75 boolean testResult = false; 77 try { 78 testResult = testStatement.execute(sql); 79 } finally { 80 if (log.isDebugEnabled() && definition.isVerbose()) { 81 log.debug(connectionPool.displayStatistics() + " - Testing connection " + proxyConnection.getId() + (testResult ? ": True" : ": False")); 82 } 83 } 84 } 85 86 proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_AVAILABLE); 87 } catch (Throwable e) { 88 proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_NULL); 90 connectionPool.removeProxyConnection(proxyConnection, "it has problems: " + e, ConnectionPool.REQUEST_EXPIRY, true); 91 } finally { 92 try { 93 testStatement.close(); 94 } catch (Throwable t) { 95 } 97 } 98 } if (proxyConnection.getAge() > definition.getMaximumConnectionLifetime()) { 101 final String reason = "age is " + proxyConnection.getAge() + "ms"; 102 if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_AVAILABLE, ProxyConnectionIF.STATUS_OFFLINE)) { 104 if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_NULL)) { 105 connectionPool.expireProxyConnection(proxyConnection, reason, ConnectionPool.REQUEST_EXPIRY); 107 } 108 } else { 109 proxyConnection.markForExpiry(reason); 113 if (log.isDebugEnabled()) { 114 log.debug(connectionPool.displayStatistics() + " - #" + FormatHelper.formatMediumNumber(proxyConnection.getId()) 115 + " marked for expiry."); 116 } 117 } } 120 if (proxyConnection.isActive()) { 123 124 long activeTime = System.currentTimeMillis() - proxyConnection.getTimeLastStartActive(); 125 126 if (activeTime < definition.getRecentlyStartedThreshold()) { 127 128 recentlyStartedActiveConnectionCountTemp++; 133 } 134 135 if (activeTime > definition.getMaximumActiveTime()) { 136 137 connectionPool.removeProxyConnection(proxyConnection, 140 "it has been active for too long", ConnectionPool.FORCE_EXPIRY, true); 141 String lastSqlCallMsg; 142 if (proxyConnection.getLastSqlCall() != null) { 143 lastSqlCallMsg = ", and the last SQL it performed is '" + proxyConnection.getLastSqlCall() + "'."; 144 } else if (!proxyConnection.getDefinition().isTrace()) { 145 lastSqlCallMsg = ", but the last SQL it performed is unknown because the trace property is not enabled."; 146 } else { 147 lastSqlCallMsg = ", but the last SQL it performed is unknown."; 148 } 149 log.warn("#" + FormatHelper.formatMediumNumber(proxyConnection.getId()) + " was active for " + activeTime 150 + " milliseconds and has been removed automaticaly. The Thread responsible was named '" 151 + proxyConnection.getRequester() + "'" + lastSqlCallMsg); 152 153 } 154 155 } 156 157 verifiedConnectionCountByState[proxyConnection.getStatus()]++; 159 160 } 161 162 calculateUpState(recentlyStartedActiveConnectionCountTemp); 163 } catch (Throwable e) { 164 log.error("Housekeeping log.error( :", e); 166 } finally { 167 connectionPool.releasePrimaryReadLock(); 168 timeLastSwept = System.currentTimeMillis(); 169 if (definition.isVerbose()) { 170 if (log.isDebugEnabled()) { 171 log.debug(connectionPool.displayStatistics() + " - House keeping triggerSweep done"); 172 } 173 } 174 } 175 176 PrototyperController.triggerSweep(definition.getAlias()); 177 178 } 179 180 184 private long getTimeSinceLastSweep() { 185 return System.currentTimeMillis() - timeLastSwept; 186 } 187 188 194 protected boolean isSweepDue() { 195 if (connectionPool.isConnectionPoolUp()) { 196 return (getTimeSinceLastSweep() > connectionPool.getDefinition().getHouseKeepingSleepTime()); 197 } else { 198 LOG.warn("House keeper is still being asked to sweep despite the connection pool being down"); 199 return false; 200 } 201 } 202 203 private void calculateUpState(int recentlyStartedActiveConnectionCount) { 204 205 try { 206 207 int calculatedUpState = StateListenerIF.STATE_QUIET; 208 209 212 213 219 220 final int availableConnectionCount = connectionPool.getAvailableConnectionCount(); 222 if (availableConnectionCount > 0 || recentlyStartedActiveConnectionCount > 0) { 223 224 227 228 if (connectionPool.getTimeOfLastRefusal() > (System.currentTimeMillis() 229 - connectionPool.getDefinition().getOverloadWithoutRefusalLifetime())) { 230 calculatedUpState = StateListenerIF.STATE_OVERLOADED; 231 } else if (connectionPool.getActiveConnectionCount() > 0) { 232 234 calculatedUpState = StateListenerIF.STATE_BUSY; 235 } 236 237 } else { 238 calculatedUpState = StateListenerIF.STATE_DOWN; 239 } 240 241 connectionPool.setUpState(calculatedUpState); 242 243 } catch (Exception e) { 244 LOG.error(e); 245 } 246 } 247 248 252 protected String getAlias() { 253 return connectionPool.getDefinition().getAlias(); 254 } 255 256 } 257 258 259 | Popular Tags |