You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2013/08/01 16:12:31 UTC

svn commit: r1509240 - in /commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2: SwallowedExceptionListener.java impl/BaseGenericObjectPool.java impl/GenericKeyedObjectPoolMXBean.java impl/GenericObjectPoolMXBean.java

Author: markt
Date: Thu Aug  1 14:12:31 2013
New Revision: 1509240

URL: http://svn.apache.org/r1509240
Log:
First pass at switching GOP and GKOP to a listener for swallowed exceptions rather than JMX notifications.

Added:
    commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/SwallowedExceptionListener.java   (with props)
Modified:
    commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
    commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java
    commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java

Added: commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/SwallowedExceptionListener.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/SwallowedExceptionListener.java?rev=1509240&view=auto
==============================================================================
--- commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/SwallowedExceptionListener.java (added)
+++ commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/SwallowedExceptionListener.java Thu Aug  1 14:12:31 2013
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.pool2;
+
+/**
+ * Pools that unavoidably swallow exceptions may be configured with an instance
+ * of this listener so the user may receive notification of when this happens.
+ * The listener should not throw an exception when called but pools calling
+ * listeners should protect themselves against exceptions anyway.
+ */
+public interface SwallowedExceptionListener {
+
+    void onSwallowException(Exception e);
+}

Propchange: commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/SwallowedExceptionListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java?rev=1509240&r1=1509239&r2=1509240&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java (original)
+++ commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java Thu Aug  1 14:12:31 2013
@@ -21,12 +21,10 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
-import java.util.Deque;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.TimerTask;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import javax.management.InstanceAlreadyExistsException;
@@ -37,7 +35,6 @@ import javax.management.MBeanRegistratio
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
 import javax.management.NotificationBroadcasterSupport;
 import javax.management.NotificationEmitter;
 import javax.management.NotificationFilter;
@@ -45,6 +42,7 @@ import javax.management.NotificationList
 import javax.management.ObjectName;
 
 import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.SwallowedExceptionListener;
 
 /**
  * Base class that provides common functionality for {@link GenericObjectPool}
@@ -73,7 +71,6 @@ public abstract class BaseGenericObjectP
      * so that rolling means may be calculated.
      */
     public static final int MEAN_TIMING_STATS_CACHE_SIZE = 100;
-    private static final int SWALLOWED_EXCEPTION_QUEUE_SIZE = 10;
 
     // Configuration attributes
     private volatile int maxTotal =
@@ -118,8 +115,6 @@ public abstract class BaseGenericObjectP
     private final ObjectName oname;
     private final NotificationBroadcasterSupport jmxNotificationSupport;
     private final String creationStackTrace;
-    private final Deque<String> swallowedExceptions = new LinkedList<String>();
-    private final AtomicInteger swallowedExcpetionCount = new AtomicInteger(0);
     private final AtomicLong borrowedCount = new AtomicLong(0);
     private final AtomicLong returnedCount = new AtomicLong(0);
     final AtomicLong createdCount = new AtomicLong(0);
@@ -131,6 +126,7 @@ public abstract class BaseGenericObjectP
     private final LinkedList<Long> waitTimes = new LinkedList<Long>(); // @GuardedBy("activeTimes") - except in initStats()
     private final Object maxBorrowWaitTimeMillisLock = new Object();
     private volatile long maxBorrowWaitTimeMillis = 0; // @GuardedBy("maxBorrowWaitTimeMillisLock")
+    private SwallowedExceptionListener swallowedExceptionListener = null;
 
 
     /**
@@ -151,11 +147,6 @@ public abstract class BaseGenericObjectP
             this.oname = null;
         }
 
-        // Populate the swallowed exceptions queue
-        for (int i = 0; i < SWALLOWED_EXCEPTION_QUEUE_SIZE; i++) {
-            swallowedExceptions.add(null);
-        }
-
         // Populate the creation stack trace
         this.creationStackTrace = getStackTrace(new Exception());
 
@@ -633,10 +624,10 @@ public abstract class BaseGenericObjectP
      * <p>Starts the evictor with the given delay. If there is an evictor
      * running when this method is called, it is stopped and replaced with a
      * new evictor with the specified delay.</p>
-     * 
+     *
      * <p>This method needs to be final, since it is called from a constructor.
      * See POOL-195.</p>
-     * 
+     *
      * @param delay time in milliseconds before start and between eviction runs
      */
     final void startEvictor(long delay) {
@@ -686,21 +677,6 @@ public abstract class BaseGenericObjectP
     }
 
     /**
-     * Lists the most recent exceptions that have been swallowed by the pool
-     * implementation. Exceptions are typically swallowed when a problem occurs
-     * while destroying an object.
-     * @return array containing stack traces of recently swallowed exceptions
-     */
-    public final String[] getSwallowedExceptions() {
-        List<String> temp =
-                new ArrayList<String>(SWALLOWED_EXCEPTION_QUEUE_SIZE);
-        synchronized (swallowedExceptions) {
-            temp.addAll(swallowedExceptions);
-        }
-        return temp.toArray(new String[SWALLOWED_EXCEPTION_QUEUE_SIZE]);
-    }
-
-    /**
      * The total number of objects successfully borrowed from this pool over the
      * lifetime of the pool.
      * @return the borrowed object count
@@ -801,6 +777,26 @@ public abstract class BaseGenericObjectP
     public abstract int getNumIdle();
 
     /**
+     * The listener used (if any) to receive notifications of exceptions
+     * unavoidably swallowed by the pool.
+     */
+    public SwallowedExceptionListener getSwallowedExceptionListener() {
+        return swallowedExceptionListener;
+    }
+
+    /**
+     * The listener used (if any) to receive notifications of exceptions
+     * unavoidably swallowed by the pool.
+     *
+     * @param swallowedExceptionListener    The listener or <code>null</code>
+     *                                      for no listener
+     */
+    public void setSwallowedExceptionListener(
+            SwallowedExceptionListener swallowedExceptionListener) {
+        this.swallowedExceptionListener = swallowedExceptionListener;
+    }
+
+    /**
      * Returns the {@link NotificationBroadcasterSupport} for the pool
      * @return JMX notification broadcaster
      */
@@ -814,19 +810,20 @@ public abstract class BaseGenericObjectP
      * @param e exception to be swallowed
      */
     final void swallowException(Exception e) {
-        String msg = getStackTrace(e);
+        SwallowedExceptionListener listener = getSwallowedExceptionListener();
 
-        ObjectName oname = getJmxName();
-        if (oname != null && !isClosed()) {
-            Notification n = new Notification(NOTIFICATION_SWALLOWED_EXCEPTION,
-                    oname, swallowedExcpetionCount.incrementAndGet(), msg);
-            getJmxNotificationSupport().sendNotification(n);
+        if (listener == null) {
+            return;
         }
 
-        // Add the exception the queue, removing the oldest
-        synchronized (swallowedExceptions) {
-            swallowedExceptions.addLast(msg);
-            swallowedExceptions.pollFirst();
+        try {
+            listener.onSwallowException(e);
+        } catch (OutOfMemoryError oome) {
+            throw oome;
+        } catch (VirtualMachineError vme) {
+            throw vme;
+        } catch (Throwable t) {
+            // Ignore. Enjoy the irony.
         }
     }
 
@@ -883,12 +880,12 @@ public abstract class BaseGenericObjectP
 
     /**
      * Registers the pool with the platform MBean server.
-     * The registered name will be 
+     * The registered name will be
      * <code>jmxNameBase + jmxNamePrefix + i</code> where i is the least
      * integer greater than or equal to 1 such that the name is not already
      * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException
      * returning null.
-     * 
+     *
      * @param jmxNameBase base JMX name for this pool
      * @param jmxNamePrefix name prefix
      * @return registered ObjectName, null if registration fails

Modified: commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java?rev=1509240&r1=1509239&r2=1509240&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java (original)
+++ commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPoolMXBean.java Thu Aug  1 14:12:31 2013
@@ -138,10 +138,6 @@ public interface GenericKeyedObjectPoolM
      */
     long getMaxBorrowWaitTimeMillis();
     /**
-     * See {@link GenericKeyedObjectPool#getSwallowedExceptions()}
-     */
-    String[] getSwallowedExceptions();
-    /**
      * See {@link GenericKeyedObjectPool#getCreationStackTrace()}
      */
     String getCreationStackTrace();

Modified: commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java?rev=1509240&r1=1509239&r2=1509240&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java (original)
+++ commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/GenericObjectPoolMXBean.java Thu Aug  1 14:12:31 2013
@@ -129,10 +129,6 @@ public interface GenericObjectPoolMXBean
      */
     long getMaxBorrowWaitTimeMillis();
     /**
-     * See {@link GenericObjectPool#getSwallowedExceptions()}
-     */
-    String[] getSwallowedExceptions();
-    /**
      * See {@link GenericObjectPool#getCreationStackTrace()}
      */
     String getCreationStackTrace();