001: /*
002: * @(#) ConnectionLeakPollThread.java 1.0 02/08/01
003: */
004:
005: package org.smartlib.pool.core;
006:
007: import java.util.*;
008:
009: /**
010: * The responsibility of this class is to poll the pools, detect leaks
011: * and release excessive free connections if required.
012: *
013: * Note: I know this class can be optimised, will do it later.
014: *
015: * @author Sachin Shekar Shetty
016: * @version 1.0, 02/08/01
017: */
018:
019: class ConnectionLeakPollThread implements Runnable {
020:
021: private Vector connectionsInUse;
022: private Vector connectionListenerList;
023: private String poolName;
024: private long sleepTime;
025: private boolean keepGoing;
026: private long leakTimeOut;
027: private static Debugger debug;
028: private Pool pool;
029:
030: /**
031: * @param connectionsInUse Vector containing the connections that
032: * are in use.
033: * @param connectionListenerList Vector of registered listenetrs.
034: * @param poolName Name of the pool.
035: * @param sleepTime Sleep time for the poll thread.
036: * @param leakTimeOut time interval after which a leak is said to
037: * have occurred.
038: * @param pool A reference to Pool implementation.
039: *
040: */
041: ConnectionLeakPollThread(Vector connectionsInUse,
042: Vector connectionListenerList, String poolName,
043: long sleepTime, long leakTimeOut, Pool pool) {
044:
045: this .connectionsInUse = connectionsInUse;
046: this .connectionListenerList = connectionListenerList;
047: this .poolName = poolName;
048: this .sleepTime = sleepTime;
049: this .leakTimeOut = leakTimeOut;
050: keepGoing = true;
051: this .pool = pool;
052: debug = new Debugger("ConnectionLeakPollThread-" + poolName,
053: true);
054:
055: }
056:
057: /**
058: * This methods notifies the registered listeners.
059: * The logic seem to contain redundent iterations, will optimize
060: * it later.
061: * @param sConn Connection for which to notify the listener.
062: */
063:
064: private void notifyAll(SmartConnection sConn) {
065:
066: for (int i = 0; i < connectionListenerList.size(); i++) {
067: //debug.print("Found Leak notifying");
068: ConnectionLeakEvent cle = new ConnectionLeakEventImpl(
069: sConn, sConn.getOwner(), sConn
070: .getLastAccessedTime(), sConn
071: .getConnectionObtainedTime(), poolName);
072: //debug.print("Found Leak notifying" + cle);
073: ConnectionLeakListener c = (ConnectionLeakListener) connectionListenerList
074: .get(i);
075: c.connectionTimeOut(cle);
076: }
077:
078: }
079:
080: // invokes the pool to release excessive connections
081: private void checkAndRelease() {
082:
083: pool.releaseConnections();
084:
085: }
086:
087: // checks and notifies the listeners
088: private void checkAndNotify() {
089:
090: for (int i = 0; i < connectionsInUse.size(); i++) {
091: SmartConnection sConn = (SmartConnection) connectionsInUse
092: .get(i);
093: // notify all the listeners
094: if (System.currentTimeMillis()
095: - sConn.getConnectionObtainedTime() >= leakTimeOut)
096: notifyAll(sConn);
097: // checks and accordingly returns connections back to the
098: // pool, one which have been idle for more than specified
099: // time
100: if (System.currentTimeMillis()
101: - sConn.getLastAccessedTime() > ((PoolMonitor) pool)
102: .getConfigMonitor().getMaxConnectionIdleTime()) {
103: debug.print("Found a Idle Connection ...");
104: sConn.forcedClose();
105: }
106: }
107:
108: }
109:
110: // Poor method, once starts running never stops untill killed,
111: // will implement stoping of polling thread at runtime in later versions.
112: public void run() {
113: debug.print("Starting Thread for detecting connection leaks");
114: while (keepGoing) {
115: debug.print("Polling .............");
116: checkAndNotify();
117: checkAndRelease();
118: try {
119: Thread.sleep(sleepTime);
120: } catch (Exception e) {
121: }
122: }
123:
124: }
125:
126: // To stop the thread, FORWARD COMPATIBILITY YOU SEE.
127: private void stop() {
128:
129: keepGoing = false;
130:
131: }
132:
133: }
|