001: /**
002: * Library name : Primrose - A Java Database Connection Pool.
003: * Published by Ben Keeping, http://primrose.org.uk .
004: * Copyright (C) 2004 Ben Keeping, primrose.org.uk
005: * Email: Use "Contact Us Form" on website
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */package uk.org.primrose.pool.core;
021:
022: import java.sql.SQLException;
023: import java.util.ArrayList;
024: import java.util.List;
025:
026: import uk.org.primrose.Constants;
027: import uk.org.primrose.Logger;
028:
029: public class PoolMonitor extends Thread {
030: Pool pool;
031: boolean run = true;
032: int sleepTime = 10000;
033: Logger logger = null;
034:
035: public PoolMonitor(Pool pool, Logger logger) {
036: this .pool = pool;
037: this .logger = logger;
038: }
039:
040: public void shutdown() {
041: run = false;
042: }
043:
044: public void run() {
045: while (run) {
046: try {
047:
048: long now = System.currentTimeMillis();
049:
050: synchronized (pool.lock) {
051: // Loop the connections, and try to find an inactive connection
052: List<ConnectionHolder> toRemove = new ArrayList<ConnectionHolder>();
053: for (ConnectionHolder ch : pool.connections) {
054: if (ch.status == Pool.CONNECTION_INACTIVE) {
055: if (pool.iIdleTime != -1) {
056: long idle = now - ch.lastUsedTimestamp;
057: if (ch.lastUsedTimestamp != 0L
058: && idle > pool.iIdleTime) {
059: logger
060: .info("[PoolMonitor@"
061: + pool.poolName
062: + "] PoolConnection@"
063: + ch.conn
064: .hashCode()
065: + " has exceeded max idle time ("
066: + pool.iIdleTime
067: + " ms) with idle time of ("
068: + idle
069: + " ms) - dropping connection");
070: try {
071: ch.conn.closePhysical();
072: } catch (SQLException sqle) {
073: logger.printStackTrace(sqle);
074: }
075: toRemove.add(ch);
076: }
077: }
078: } else if (ch.status == Pool.CONNECTION_ACTIVE) {
079: if (pool.iKillActiveConnectionsOverAge != -1) {
080: long active = now - ch.connOpenedDate;
081: if (ch.connOpenedDate != 0L
082: && active > pool.iKillActiveConnectionsOverAge) {
083: StringBuffer stack = new StringBuffer();
084: StackTraceElement[] els = ch.callStack;
085: for (StackTraceElement el : els) {
086: stack.append("\t");
087: stack.append(el.toString());
088: stack.append("\n");
089: }
090: String message = ("[PoolMonitor@"
091: + pool.poolName
092: + "] PoolConnection@"
093: + ch.conn.hashCode()
094: + " has exceeded max execution time ("
095: + pool.iKillActiveConnectionsOverAge
096: + " ms) with active time of ("
097: + active
098: + " ms) - killing off connection\n" + stack
099: .toString());
100: logger.email(Constants.KILL_EVENT,
101: message);
102: logger.info(message);
103:
104: try {
105: ch.conn.closePhysical();
106: } catch (SQLException sqle) {
107: logger.printStackTrace(sqle);
108: }
109: toRemove.add(ch);
110:
111: }
112: }
113: }
114:
115: }
116:
117: if (toRemove.size() > 0) {
118: pool.connections.removeAll(toRemove);
119: }
120: }
121:
122: } catch (Exception e) {
123: logger.printStackTrace(e);
124: }
125:
126: if (run)
127: try {
128: Thread.sleep(sleepTime);
129: } catch (InterruptedException ie) {
130: }
131: }
132: logger.verbose("[PoolMonitor@" + pool.poolName + "] Exiting.");
133: }
134: }
|