Author: fhanik
Date: Fri Nov 13 21:53:13 2009
New Revision: 836011

URL: http://svn.apache.org/viewvc?rev=836011&view=rev
Log:
Implement suspectTimeout to allow JMX notifications and log events to take 
place if a connection is checked out for too long. But don't abandon/close the 
connection.

Modified:
    tomcat/trunk/modules/jdbc-pool/.classpath
    tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
    
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java

Modified: tomcat/trunk/modules/jdbc-pool/.classpath
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/.classpath?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/.classpath (original)
+++ tomcat/trunk/modules/jdbc-pool/.classpath Fri Nov 13 21:53:13 2009
@@ -6,5 +6,6 @@
        <classpathentry kind="con" 
path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
        <classpathentry kind="var" 
path="TOMCAT_LIBS_BASE/tomcat6-deps/dbcp/tomcat-dbcp.jar" 
sourcepath="/TOMCAT_LIBS_BASE/tomcat6-deps/dbcp/src/java"/>
        <classpathentry kind="con" 
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry kind="lib" 
path="/development/tomcat/trunk/trunk/modules/jdbc-pool/includes/h2/bin/h2-1.1.115.jar"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>

Modified: tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml (original)
+++ tomcat/trunk/modules/jdbc-pool/doc/jdbc-pool.xml Fri Nov 13 21:53:13 2009
@@ -78,13 +78,16 @@
       <li>Asynchronous connection retrieval - you can queue your request for a 
connection and receive a Future&lt;Connection&gt; back.</li>    
       <li>Better idle connection handling. Instead of closing connections 
directly, it can still pool connections and sizes the idle pool with a smarter 
algorithm.</li>    
       <li>You can decide at what moment connections are considered abandoned, 
is it when the pool is full, or directly at a timeout
-          by specifying a threshold.
+          by specifying a pool usage threshold.
       </li>    
       <li>The abandon connection timer will reset upon a statement/query 
activity. Allowing a connections that is in use for a long time to not timeout.
           This is achieved using the ResetAbandonedTimer
       </li>    
       <li>Close connections after they have been connected for a certain time. 
Age based close upon return to the pool.
-      </li>    
+      </li>   
+      <li>Get JMX notifications and log entries when connections are suspected 
for being abandoned. This is similar to
+          the <code>removeAbandonedTimeout</code> but it doesn't take any 
action, only reports the information. 
+          This is achieved using the <code>suspectTimeout</code> 
attribute.</li> 
     </ol>
   </p>
 
@@ -388,6 +391,16 @@
          The default value is <code>true</code>.
       </p> 
     </attribute>    
+    <attribute name="suspectTimeout" required="false">
+      <p>(int) Timeout value in seconds. Default value is <code>0</code>.<br/>
+           Similar to to the <code>removeAbandonedTimeout</code> value but 
instead of treating the connection
+           as abandoned, and potentially closing the connection, this simply 
logs the warning if 
+           <code>logAbandoned</code> is set to true. If this value is equal or 
less than 0, no suspect 
+           checking will be performed. Suspect checking only takes place if 
the timeout value is larger than 0 and
+           the connection was not abandoned or if abandon check is disabled. 
If a connection is suspect a WARN message gets
+           logged and a JMX notification gets sent once. 
+      </p>
+    </attribute>
   </attributes>  
   </subsection>
 </section>

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/ConnectionPool.java
 Fri Nov 13 21:53:13 2009
@@ -475,6 +475,32 @@
             con.unlock();
         }
     }
+    
+    /**
+     * thread safe way to abandon a connection
+     * signals a connection to be abandoned.
+     * this will disconnect the connection, and log the stack trace if 
logAbanded=true
+     * @param con PooledConnection
+     */
+    protected void suspect(PooledConnection con) {
+        if (con == null)
+            return;
+        if (con.isSuspect())
+            return;
+        try {
+            con.lock();
+            String trace = con.getStackTrace();
+            if (getPoolProperties().isLogAbandoned()) {
+                log.warn("Connection has been marked suspect, possibly 
abandoned " + con + "["+(System.currentTimeMillis()-con.getTimestamp())+" 
ms.]:" + trace);
+            }
+            if (jmxPool!=null) {
+                
jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.SUSPECT_ABANDONED_NOTIFICATION,
 trace);
+            }
+            con.setSuspect(true);
+        } finally {
+            con.unlock();
+        }
+    }
 
     /**
      * thread safe way to release a connection
@@ -786,8 +812,8 @@
     public void checkAbandoned() {
         try {
             if (busy.size()==0) return;
-            if (!shouldAbandon()) return;
             Iterator<PooledConnection> locked = busy.iterator();
+            int sto = getPoolProperties().getSuspectTimeout();
             while (locked.hasNext()) {
                 PooledConnection con = locked.next();
                 boolean setToNull = false;
@@ -799,10 +825,12 @@
                         continue;
                     long time = con.getTimestamp();
                     long now = System.currentTimeMillis();
-                    if ((now - time) > con.getAbandonTimeout()) {
+                    if (shouldAbandon() && (now - time) > 
con.getAbandonTimeout()) {
                         busy.remove(con);
                         abandon(con);
                         setToNull = true;
+                    } else if (sto > 0 && (now - time) > (sto*1000)) {
+                        suspect(con);
                     } else {
                         //do nothing
                     } //end if

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceProxy.java
 Fri Nov 13 21:53:13 2009
@@ -516,6 +516,23 @@
 
     }    
     
+    
+    /**
+     * {...@inheritdoc}
+     */
+    @Override
+    public int getSuspectTimeout() {
+        return getPoolProperties().getSuspectTimeout(); 
+    }
+
+    /**
+     * {...@inheritdoc}
+     */
+    @Override
+    public void setSuspectTimeout(int seconds) {
+        getPoolProperties().setSuspectTimeout(seconds);
+    }
+    
   
//===============================================================================
 //  Expose JMX attributes through Tomcat's dynamic reflection
 
//===============================================================================

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolConfiguration.java
 Fri Nov 13 21:53:13 2009
@@ -698,5 +698,24 @@
      * @param useLock set to true if a lock should be used on connection 
operations
      */
     public void setUseLock(boolean useLock);
+    
+    /**
+     * Similar to {...@link #setRemoveAbandonedTimeout(int)} but instead of 
treating the connection
+     * as abandoned, and potentially closing the connection, this simply logs 
the warning if 
+     * {...@link #isLogAbandoned()} returns true. If this value is equal or 
less than 0, no suspect 
+     * checking will be performed. Suspect checking only takes place if the 
timeout value is larger than 0 and
+     * the connection was not abandoned or if abandon check is disabled. If a 
connection is suspect a WARN message gets
+     * logged and a JMX notification gets sent once. 
+     * @param seconds - the amount of time in seconds that has to pass before 
a connection is marked suspect. 
+     */
+    public void setSuspectTimeout(int seconds);
+    
+    /**
+     * Returns the time in seconds to pass before a connection is marked an 
abanoned suspect.
+     * Any value lesser than or equal to 0 means the check is disabled. 
+     * @return Returns the time in seconds to pass before a connection is 
marked an abanoned suspect.
+     */
+    public int getSuspectTimeout();
+    
 
 }
\ No newline at end of file

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PoolProperties.java
 Fri Nov 13 21:53:13 2009
@@ -74,6 +74,8 @@
     protected long maxAge = 0;
     protected boolean useLock = false;
     private InterceptorDefinition[] interceptors = null;
+    protected int suspectTimeout = 0;
+    
     
     /** 
      * {...@inheritdoc}
@@ -718,14 +720,32 @@
         return defaultReadOnly;
     }
     
+    
+    /**
+     * {...@inheritdoc}
+     */
+    @Override
+    public int getSuspectTimeout() {
+        return this.suspectTimeout;
+    }
+
+    /**
+     * {...@inheritdoc}
+     */
+    @Override
+    public void setSuspectTimeout(int seconds) {
+        this.suspectTimeout = seconds;
+    }
+
     /** 
      * {...@inheritdoc}
      */
     @Override
     public boolean isPoolSweeperEnabled() {
-        boolean result = getTimeBetweenEvictionRunsMillis()>0;
-        result = result && (isRemoveAbandoned() && 
getRemoveAbandonedTimeout()>0);
-        result = result || (isTestWhileIdle() && getValidationQuery()!=null);
+        boolean timer = getTimeBetweenEvictionRunsMillis()>0;
+        boolean result = timer && (isRemoveAbandoned() && 
getRemoveAbandonedTimeout()>0);
+        result = result || (timer && getSuspectTimeout()>0); 
+        result = result || (timer && isTestWhileIdle() && 
getValidationQuery()!=null);
         return result;
     }
     

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/PooledConnection.java
 Fri Nov 13 21:53:13 2009
@@ -111,6 +111,8 @@
     
     private AtomicBoolean released = new AtomicBoolean(false);
     
+    private volatile boolean suspect = false;
+    
     /**
      * Constructor
      * @param prop - pool properties
@@ -390,6 +392,18 @@
      */
     public void setTimestamp(long timestamp) {
         this.timestamp = timestamp;
+        setSuspect(false);
+    }
+    
+    
+    
+
+    public boolean isSuspect() {
+        return suspect;
+    }
+
+    public void setSuspect(boolean suspect) {
+        this.suspect = suspect;
     }
 
     /**

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/interceptor/AbstractQueryReport.java
 Fri Nov 13 21:53:13 2009
@@ -73,7 +73,7 @@
      * Invoked when a query execution, a call to execute/executeQuery or 
executeBatch failed.
      * @param query the query that was executed and failed
      * @param args the arguments to the execution
-     * @param name the name of the method used to execute {...@link 
AbstractCreateStatementInterceptor#executes}
+     * @param name the name of the method used to execute {...@link 
AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
      * @param start the time the query execution started
      * @param t the exception that happened
      * @return - the SQL that was executed or the string &quot;batch&quot; if 
it was a batch execution 
@@ -92,7 +92,7 @@
      * Invoked when a query execution, a call to execute/executeQuery or 
executeBatch succeeded and was within the timing threshold
      * @param query the query that was executed and failed
      * @param args the arguments to the execution
-     * @param name the name of the method used to execute {...@link 
AbstractCreateStatementInterceptor#executes}
+     * @param name the name of the method used to execute {...@link 
AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
      * @param start the time the query execution started
      * @param delta the time the execution took
      * @return - the SQL that was executed or the string &quot;batch&quot; if 
it was a batch execution 
@@ -111,7 +111,7 @@
      * Invoked when a query execution, a call to execute/executeQuery or 
executeBatch succeeded and was exceeded the timing threshold
      * @param query the query that was executed and failed
      * @param args the arguments to the execution
-     * @param name the name of the method used to execute {...@link 
AbstractCreateStatementInterceptor#executes}
+     * @param name the name of the method used to execute {...@link 
AbstractCreateStatementInterceptor#isExecute(Method, boolean)}
      * @param start the time the query execution started
      * @param delta the time the execution took
      * @return - the SQL that was executed or the string &quot;batch&quot; if 
it was a batch execution 

Modified: 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java?rev=836011&r1=836010&r2=836011&view=diff
==============================================================================
--- 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
 (original)
+++ 
tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/jmx/ConnectionPool.java
 Fri Nov 13 21:53:13 2009
@@ -72,6 +72,7 @@
     public static final String NOTIFY_ABANDON = "CONNECTION ABANDONED";
     public static final String SLOW_QUERY_NOTIFICATION = "SLOW QUERY";
     public static final String FAILED_QUERY_NOTIFICATION = "FAILED QUERY";
+    public static final String SUSPECT_ABANDONED_NOTIFICATION = "SUSPECT 
CONNETION ABANDONED";
     
     
     
@@ -86,7 +87,7 @@
     } 
     
     public static MBeanNotificationInfo[] getDefaultNotificationInfo() {
-        String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, 
NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION, FAILED_QUERY_NOTIFICATION}; 
+        String[] types = new String[] {NOTIFY_INIT, NOTIFY_CONNECT, 
NOTIFY_ABANDON, SLOW_QUERY_NOTIFICATION, FAILED_QUERY_NOTIFICATION, 
SUSPECT_ABANDONED_NOTIFICATION}; 
         String name = Notification.class.getName(); 
         String description = "A connection pool error condition was met."; 
         MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, 
description); 
@@ -553,5 +554,21 @@
         // TODO Auto-generated method stub
         
     }
+    
+    /**
+    * {...@inheritdoc}
+    */
+   @Override
+   public int getSuspectTimeout() {
+       return getPoolProperties().getSuspectTimeout(); 
+   }
+
+   /**
+    * {...@inheritdoc}
+    */
+   @Override
+   public void setSuspectTimeout(int seconds) {
+       //no op
+   }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to