camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject svn commit: r1394991 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/api/management/mbean/ main/java/org/apache/camel/impl/ main/java/org/apache/camel/management/ main/java/org/apache/camel/management/mbean/ main/java/org/apache/camel/util...
Date Sat, 06 Oct 2012 10:44:15 GMT
Author: davsclaus
Date: Sat Oct  6 10:44:14 2012
New Revision: 1394991

URL: http://svn.apache.org/viewvc?rev=1394991&view=rev
Log:
CAMEL-5688: LRUCache will stop service on eviction.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedConsumerCacheMBean.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedProducerCacheMBean.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EndpointRegistry.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedConsumerCache.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProducerCache.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUCache.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedConsumerCacheMBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedConsumerCacheMBean.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedConsumerCacheMBean.java
(original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedConsumerCacheMBean.java
Sat Oct  6 10:44:14 2012
@@ -36,6 +36,9 @@ public interface ManagedConsumerCacheMBe
     @ManagedAttribute(description = "Cache misses")
     Long getMisses();
 
+    @ManagedAttribute(description = "Cache evicted")
+    Long getEvicted();
+
     @ManagedOperation(description = "Reset cache statistics")
     void resetStatistics();
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedProducerCacheMBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedProducerCacheMBean.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedProducerCacheMBean.java
(original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedProducerCacheMBean.java
Sat Oct  6 10:44:14 2012
@@ -36,6 +36,9 @@ public interface ManagedProducerCacheMBe
     @ManagedAttribute(description = "Cache misses")
     Long getMisses();
 
+    @ManagedAttribute(description = "Cache evicted")
+    Long getEvicted();
+
     @ManagedOperation(description = "Reset cache statistics")
     void resetStatistics();
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ConsumerCache.java Sat Oct
 6 10:44:14 2012
@@ -190,6 +190,22 @@ public class ConsumerCache extends Servi
     }
 
     /**
+     * Gets the cache evicted statistic
+     * <p/>
+     * Will return <tt>-1</tt> if it cannot determine this if a custom cache
was used.
+     *
+     * @return the evicted
+     */
+    public long getEvicted() {
+        long evicted = -1;
+        if (consumers instanceof LRUCache) {
+            LRUCache<String, PollingConsumer> cache = (LRUCache<String, PollingConsumer>)consumers;
+            evicted = cache.getEvicted();
+        }
+        return evicted;
+    }
+
+    /**
      * Resets the cache statistics
      */
     public void resetCacheStatistics() {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EndpointRegistry.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EndpointRegistry.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EndpointRegistry.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/EndpointRegistry.java Sat Oct
 6 10:44:14 2012
@@ -35,7 +35,8 @@ public class EndpointRegistry extends LR
     private final CamelContext context;
 
     public EndpointRegistry(CamelContext context) {
-        super(CamelContextHelper.getMaximumEndpointCacheSize(context));
+        // do not stop on eviction, as the endpoint may still be in use
+        super(CamelContextHelper.getMaximumEndpointCacheSize(context), CamelContextHelper.getMaximumEndpointCacheSize(context),
false);
         this.context = context;
     }
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ProducerCache.java Sat Oct
 6 10:44:14 2012
@@ -480,6 +480,22 @@ public class ProducerCache extends Servi
     }
 
     /**
+     * Gets the cache evicted statistic
+     * <p/>
+     * Will return <tt>-1</tt> if it cannot determine this if a custom cache
was used.
+     *
+     * @return the evicted
+     */
+    public long getEvicted() {
+        long evicted = -1;
+        if (producers instanceof LRUCache) {
+            LRUCache<String, Producer> cache = (LRUCache<String, Producer>)producers;
+            evicted = cache.getEvicted();
+        }
+        return evicted;
+    }
+
+    /**
      * Resets the cache statistics
      */
     public void resetCacheStatistics() {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
(original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
Sat Oct  6 10:44:14 2012
@@ -65,7 +65,7 @@ public class MBeanInfoAssembler implemen
     @Override
     public void stop() throws Exception {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Clearing cache[size={}, hits={}, misses={}]", new Object[]{cache.size(),
cache.getHits(), cache.getMisses()});
+            LOG.debug("Clearing cache[size={}, hits={}, misses={}, evicted={}]", new Object[]{cache.size(),
cache.getHits(), cache.getMisses(), cache.getEvicted()});
         }
         cache.clear();
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedConsumerCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedConsumerCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedConsumerCache.java
(original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedConsumerCache.java
Sat Oct  6 10:44:14 2012
@@ -60,6 +60,10 @@ public class ManagedConsumerCache extend
         return consumerCache.getMisses();
     }
 
+    public Long getEvicted() {
+        return consumerCache.getEvicted();
+    }
+
     public void resetStatistics() {
         consumerCache.resetCacheStatistics();
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProducerCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProducerCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProducerCache.java
(original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProducerCache.java
Sat Oct  6 10:44:14 2012
@@ -60,6 +60,10 @@ public class ManagedProducerCache extend
         return producerCache.getMisses();
     }
 
+    public Long getEvicted() {
+        return producerCache.getEvicted();
+    }
+
     public void resetStatistics() {
         producerCache.resetCacheStatistics();
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/IntrospectionSupport.java Sat
Oct  6 10:44:14 2012
@@ -101,7 +101,7 @@ public final class IntrospectionSupport 
      */
     public static void stop() {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Clearing cache[size={}, hits={}, misses={}]", new Object[]{CACHE.size(),
CACHE.getHits(), CACHE.getMisses()});
+            LOG.debug("Clearing cache[size={}, hits={}, misses={}, evicted={}]", new Object[]{CACHE.size(),
CACHE.getHits(), CACHE.getMisses(), CACHE.getEvicted()});
         }
         CACHE.clear();
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUCache.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUCache.java Sat Oct  6 10:44:14
2012
@@ -23,38 +23,69 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
 import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
+import com.googlecode.concurrentlinkedhashmap.EvictionListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * A Least Recently Used Cache
+ * A Least Recently Used Cache.
+ * <p/>
+ * If this cache stores {@link org.apache.camel.Service} then this implementation will on
eviction
+ * invoke the {@link org.apache.camel.Service#stop()} method, to auto-stop the service.
  *
- * @version 
+ * @see LRUSoftCache
+ * @see LRUWeakCache
  */
-public class LRUCache<K, V> implements Map<K, V>, Serializable {
+public class LRUCache<K, V> implements Map<K, V>, EvictionListener<K, V>,
Serializable {
     private static final long serialVersionUID = -342098639681884414L;
+    private static final Logger LOG = LoggerFactory.getLogger(LRUCache.class);
     
     private int maxCacheSize = 10000;
+    private boolean stopOnEviction;
     private final AtomicLong hits = new AtomicLong();
     private final AtomicLong misses = new AtomicLong();
+    private final AtomicLong evicted = new AtomicLong();
     private ConcurrentLinkedHashMap<K, V> map;
 
+    /**
+     * Constructs an empty <tt>LRUCache</tt> instance with the
+     * specified maximumCacheSize, and will stop on eviction.
+     *
+     * @param maximumCacheSize the max capacity.
+     * @throws IllegalArgumentException if the initial capacity is negative
+     */
     public LRUCache(int maximumCacheSize) {
         this(maximumCacheSize, maximumCacheSize);
     }
 
     /**
      * Constructs an empty <tt>LRUCache</tt> instance with the
-     * specified initial capacity, maximumCacheSize,load factor and ordering mode.
+     * specified initial capacity, maximumCacheSize, and will stop on eviction.
      *
      * @param initialCapacity  the initial capacity.
      * @param maximumCacheSize the max capacity.
      * @throws IllegalArgumentException if the initial capacity is negative
-     *                                  or the load factor is non positive.
      */
     public LRUCache(int initialCapacity, int maximumCacheSize) {
+        this(initialCapacity, maximumCacheSize, true);
+    }
+
+    /**
+     * Constructs an empty <tt>LRUCache</tt> instance with the
+     * specified initial capacity, maximumCacheSize,load factor and ordering mode.
+     *
+     * @param initialCapacity  the initial capacity.
+     * @param maximumCacheSize the max capacity.
+     * @param stopOnEviction   whether to stop service on eviction.
+     * @throws IllegalArgumentException if the initial capacity is negative
+     */
+    public LRUCache(int initialCapacity, int maximumCacheSize, boolean stopOnEviction) {
         map = new ConcurrentLinkedHashMap.Builder<K, V>()
-            .initialCapacity(initialCapacity)
-            .maximumWeightedCapacity(maximumCacheSize).build();
+                .initialCapacity(initialCapacity)
+                .maximumWeightedCapacity(maximumCacheSize)
+                .listener(this).build();
         this.maxCacheSize = maximumCacheSize;
+        this.stopOnEviction = stopOnEviction;
     }
 
     @Override
@@ -123,6 +154,20 @@ public class LRUCache<K, V> implements M
         return map.ascendingMap().entrySet();
     }
 
+    @Override
+    public void onEviction(K key, V value) {
+        evicted.incrementAndGet();
+        LOG.trace("onEviction {} -> {}", key, value);
+        if (stopOnEviction) {
+            try {
+                // stop service as its evicted from cache
+                ServiceHelper.stopService(value);
+            } catch (Exception e) {
+                LOG.warn("Error stopping service: " + value + ". This exception will be ignored.",
e);
+            }
+        }
+    }
+
     /**
      * Gets the number of cache hits
      */
@@ -138,6 +183,13 @@ public class LRUCache<K, V> implements M
     }
 
     /**
+     * Gets the number of evicted entries.
+     */
+    public long getEvicted() {
+        return evicted.get();
+    }
+
+    /**
      * Returns the maxCacheSize.
      */
     public int getMaxCacheSize() {
@@ -150,6 +202,7 @@ public class LRUCache<K, V> implements M
     public void resetStatistics() {
         hits.set(0);
         misses.set(0);
+        evicted.set(0);
     }
 
     @Override

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUSoftCache.java Sat Oct 
6 10:44:14 2012
@@ -46,6 +46,9 @@ import java.util.Set;
  * <p/>
  * The {@link #containsValue(Object)} method should <b>not</b> be used as it's
not adjusted to check
  * for the existence of a value without catering for the soft references.
+ * <p/>
+ * Notice that if the JVM reclaim memory the content of this cache may be garbage collected,
without any
+ * eviction notifications.
  *
  * @see LRUCache
  * @see LRUWeakCache
@@ -61,6 +64,10 @@ public class LRUSoftCache<K, V> extends 
         super(initialCapacity, maximumCacheSize);
     }
 
+    public LRUSoftCache(int initialCapacity, int maximumCacheSize, boolean stopOnEviction)
{
+        super(initialCapacity, maximumCacheSize, stopOnEviction);
+    }
+
     @Override
     @SuppressWarnings("unchecked")
     public V put(K key, V value) {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/LRUWeakCache.java Sat Oct 
6 10:44:14 2012
@@ -46,6 +46,9 @@ import java.util.Set;
  * <p/>
  * The {@link #containsValue(Object)} method should <b>not</b> be used as it's
not adjusted to check
  * for the existence of a value without catering for the soft references.
+ * <p/>
+ * Notice that if the JVM reclaim memory the content of this cache may be garbage collected,
without any
+ * eviction notifications.
  *
  * @see LRUCache
  * @see LRUSoftCache

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java?rev=1394991&r1=1394990&r2=1394991&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/LRUCacheTest.java Sat Oct 
6 10:44:14 2012
@@ -44,6 +44,59 @@ public class LRUCacheTest extends TestCa
         assertSame(service2, cache.get("B"));
     }
 
+    public void testLRUCacheEviction() {
+        MyService service1 = new MyService();
+        MyService service2 = new MyService();
+        MyService service3 = new MyService();
+        MyService service4 = new MyService();
+        MyService service5 = new MyService();
+        MyService service6 = new MyService();
+        MyService service7 = new MyService();
+        MyService service8 = new MyService();
+        MyService service9 = new MyService();
+        MyService service10 = new MyService();
+        MyService service11 = new MyService();
+        MyService service12 = new MyService();
+
+        cache.put("A", service1);
+        assertNull(service1.getStopped());
+        cache.put("B", service2);
+        assertNull(service2.getStopped());
+        cache.put("C", service3);
+        assertNull(service3.getStopped());
+        cache.put("D", service4);
+        assertNull(service4.getStopped());
+        cache.put("E", service5);
+        assertNull(service5.getStopped());
+        cache.put("F", service6);
+        assertNull(service6.getStopped());
+        cache.put("G", service7);
+        assertNull(service7.getStopped());
+        cache.put("H", service8);
+        assertNull(service8.getStopped());
+        cache.put("I", service9);
+        assertNull(service9.getStopped());
+        cache.put("J", service10);
+        assertNull(service10.getStopped());
+
+        // we are now full
+        assertEquals(10, cache.size());
+
+        cache.put("K", service11);
+        assertNull(service11.getStopped());
+
+        // should evict the eldest, and stop the service
+        assertTrue(service1.getStopped());
+
+        cache.put("L", service12);
+        assertNull(service12.getStopped());
+
+        // should evict the eldest, and stop the service
+        assertTrue(service2.getStopped());
+
+        assertEquals(10, cache.size());
+    }
+
     public void testLRUCacheHitsAndMisses() {
         MyService service1 = new MyService();
         MyService service2 = new MyService();
@@ -92,10 +145,18 @@ public class LRUCacheTest extends TestCa
     }
 
     private static final class MyService implements Service {
+
+        private Boolean stopped;
+
         public void start() throws Exception {
         }
 
         public void stop() throws Exception {
+            stopped = true;
+        }
+
+        public Boolean getStopped() {
+            return stopped;
         }
     }
 }



Mime
View raw message