You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/04/02 12:35:27 UTC

[camel] 02/02: CAMEL-16444: camel-core - Optimize endpoint lookup

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 09586e7defaa287836da9e11e8ac0cc84f53027f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Apr 2 14:27:27 2021 +0200

    CAMEL-16444: camel-core - Optimize endpoint lookup
---
 .../camel/impl/engine/AbstractDynamicRegistry.java | 37 +++++++++-------------
 .../camel/impl/engine/DefaultEndpointRegistry.java |  9 ++++--
 .../impl/engine/DefaultTransformerRegistry.java    |  8 ++---
 .../impl/engine/DefaultValidatorRegistry.java      |  8 ++---
 .../camel/impl/engine/PooledExchangeFactory.java   |  6 ++--
 .../camel/impl/DefaultEndpointRegistryTest.java    | 31 ++++++++++++++++++
 .../management/ManagedEndpointRegistryTest.java    |  2 +-
 .../management/ManagedTransformerRegistryTest.java |  6 ++--
 .../management/ManagedValidatorRegistryTest.java   |  6 ++--
 9 files changed, 71 insertions(+), 42 deletions(-)

diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractDynamicRegistry.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractDynamicRegistry.java
index 2dee3a7..888e05c 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractDynamicRegistry.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractDynamicRegistry.java
@@ -33,8 +33,8 @@ import org.apache.camel.support.LRUCacheFactory;
 import org.apache.camel.support.service.ServiceHelper;
 
 /**
- * Base implementation for {@link org.apache.camel.spi.TransformerRegistry},
- * {@link org.apache.camel.spi.ValidatorRegistry} and {@link org.apache.camel.spi.EndpointRegistry}.
+ * Base implementation for {@link org.apache.camel.spi.EndpointRegistry},
+ * {@link org.apache.camel.spi.TransformerRegistry}, and {@link org.apache.camel.spi.ValidatorRegistry}.
  */
 public class AbstractDynamicRegistry<K, V> extends AbstractMap<K, V> implements StaticService {
 
@@ -48,9 +48,9 @@ public class AbstractDynamicRegistry<K, V> extends AbstractMap<K, V> implements
         this.context = (ExtendedCamelContext) context;
         this.routeController = context.getRouteController();
         this.maxCacheSize = maxCacheSize;
-        // do not stop on eviction, as the transformer may still be in use
+        // do not stop on eviction, as the endpoint or transformer may still be in use
         this.dynamicMap = LRUCacheFactory.newLRUCache(this.maxCacheSize, this.maxCacheSize, false);
-        // static map to hold transformers we do not want to be evicted
+        // static map to hold endpoint or transformer we do not want to be evicted
         this.staticMap = new ConcurrentHashMap<>();
     }
 
@@ -63,42 +63,38 @@ public class AbstractDynamicRegistry<K, V> extends AbstractMap<K, V> implements
 
     @Override
     public V get(Object o) {
-        // try static map first
+        // keep this get optimized to only lookup
+        // try static map first and fallback to dynamic
         V answer = staticMap.get(o);
         if (answer == null) {
             answer = dynamicMap.get(o);
-            // TODO: avoid this expensive lookup, since its a get lookup which we want to be fast
-            // TODO: instead use some kind of event notifier to transfer from dynamic to static
-            if (answer != null && (context.isSetupRoutes() || routeController.isStartingRoutes())) {
-                dynamicMap.remove(o);
-                staticMap.put((K) o, answer);
-            }
         }
         return answer;
     }
 
     @Override
-    public V put(K key, V transformer) {
+    public V put(K key, V obj) {
         // at first we must see if the key already exists and then replace it back, so it stays the same spot
         V answer = staticMap.remove(key);
         if (answer != null) {
             // replace existing
-            staticMap.put(key, transformer);
+            staticMap.put(key, obj);
             return answer;
         }
 
         answer = dynamicMap.remove(key);
         if (answer != null) {
             // replace existing
-            dynamicMap.put(key, transformer);
+            dynamicMap.put(key, obj);
             return answer;
         }
 
-        // we want transformers to be static if they are part of setting up or starting routes
-        if (context.isSetupRoutes() || routeController.isStartingRoutes()) {
-            answer = staticMap.put(key, transformer);
+        // we want endpoint or transformer to be static if they are part of
+        // starting up camel, or if new routes are being setup/added or routes started later
+        if (!context.isStarted() || context.isSetupRoutes() || routeController.isStartingRoutes()) {
+            answer = staticMap.put(key, obj);
         } else {
-            answer = dynamicMap.put(key, transformer);
+            answer = dynamicMap.put(key, obj);
         }
 
         return answer;
@@ -168,9 +164,6 @@ public class AbstractDynamicRegistry<K, V> extends AbstractMap<K, V> implements
         return maxCacheSize;
     }
 
-    /**
-     * Purges the cache
-     */
     public void purge() {
         // only purge the dynamic part
         dynamicMap.clear();
@@ -198,7 +191,7 @@ public class AbstractDynamicRegistry<K, V> extends AbstractMap<K, V> implements
 
     @Override
     public String toString() {
-        return "Registry for " + context.getName() + ", capacity: " + maxCacheSize;
+        return "Registry for " + context.getName() + " [capacity: " + maxCacheSize + "]";
     }
 
 }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultEndpointRegistry.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultEndpointRegistry.java
index 7d37bcd..1449e02 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultEndpointRegistry.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultEndpointRegistry.java
@@ -36,7 +36,12 @@ public class DefaultEndpointRegistry extends AbstractDynamicRegistry<NormalizedU
 
     public DefaultEndpointRegistry(CamelContext context, Map<NormalizedUri, Endpoint> endpoints) {
         this(context);
-        putAll(endpoints);
+        if (!context.isStarted()) {
+            // optimize to put all into the static map as we are not started
+            staticMap.putAll(endpoints);
+        } else {
+            putAll(endpoints);
+        }
     }
 
     @Override
@@ -51,6 +56,6 @@ public class DefaultEndpointRegistry extends AbstractDynamicRegistry<NormalizedU
 
     @Override
     public String toString() {
-        return "EndpointRegistry for " + context.getName() + ", capacity: " + maxCacheSize;
+        return "EndpointRegistry for " + context.getName() + " [capacity: " + maxCacheSize + "]";
     }
 }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java
index 66fa63c..23000c8 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultTransformerRegistry.java
@@ -83,10 +83,10 @@ public class DefaultTransformerRegistry extends AbstractDynamicRegistry<Transfor
     }
 
     @Override
-    public Transformer put(TransformerKey key, Transformer transformer) {
+    public Transformer put(TransformerKey key, Transformer obj) {
         // ensure transformer is started before its being used
-        ServiceHelper.startService(transformer);
-        return super.put(key, transformer);
+        ServiceHelper.startService(obj);
+        return super.put(key, obj);
     }
 
     @Override
@@ -111,7 +111,7 @@ public class DefaultTransformerRegistry extends AbstractDynamicRegistry<Transfor
 
     @Override
     public String toString() {
-        return "TransformerRegistry for " + context.getName() + ", capacity: " + maxCacheSize;
+        return "TransformerRegistry for " + context.getName() + " [capacity: " + maxCacheSize + "]";
     }
 
 }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java
index 792b40b..1314e05 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultValidatorRegistry.java
@@ -55,14 +55,14 @@ public class DefaultValidatorRegistry extends AbstractDynamicRegistry<ValidatorK
 
     @Override
     public String toString() {
-        return "ValidatorRegistry for " + context.getName() + ", capacity: " + maxCacheSize;
+        return "ValidatorRegistry for " + context.getName() + " [capacity: " + maxCacheSize + "]";
     }
 
     @Override
-    public Validator put(ValidatorKey key, Validator validator) {
+    public Validator put(ValidatorKey key, Validator obj) {
         // ensure validator is started before its being used
-        ServiceHelper.startService(validator);
-        return super.put(key, validator);
+        ServiceHelper.startService(obj);
+        return super.put(key, obj);
     }
 
 }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PooledExchangeFactory.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PooledExchangeFactory.java
index f45d105..99289e3 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PooledExchangeFactory.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PooledExchangeFactory.java
@@ -76,7 +76,7 @@ public final class PooledExchangeFactory extends PrototypeExchangeFactory {
                 statistics.acquired.increment();
             }
             // reset exchange for reuse
-            PooledExchange ee = exchange.adapt(PooledExchange.class);
+            PooledExchange ee = (PooledExchange) exchange;
             ee.reset(System.currentTimeMillis());
         }
         return exchange;
@@ -96,7 +96,7 @@ public final class PooledExchangeFactory extends PrototypeExchangeFactory {
                 statistics.acquired.increment();
             }
             // reset exchange for reuse
-            PooledExchange ee = exchange.adapt(PooledExchange.class);
+            PooledExchange ee = (PooledExchange) exchange;
             ee.reset(System.currentTimeMillis());
         }
         return exchange;
@@ -106,7 +106,7 @@ public final class PooledExchangeFactory extends PrototypeExchangeFactory {
     public boolean release(Exchange exchange) {
         try {
             // done exchange before returning back to pool
-            PooledExchange ee = exchange.adapt(PooledExchange.class);
+            PooledExchange ee = (PooledExchange) exchange;
             boolean force = !ee.isAutoRelease();
             ee.done(force);
             ee.onDone(null);
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultEndpointRegistryTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultEndpointRegistryTest.java
index c5bb2f3..2d8cdc8 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultEndpointRegistryTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultEndpointRegistryTest.java
@@ -16,7 +16,9 @@
  */
 package org.apache.camel.impl;
 
+import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.engine.DefaultEndpointRegistry;
+import org.apache.camel.spi.EndpointRegistry;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -29,12 +31,41 @@ public class DefaultEndpointRegistryTest {
         ctx.start();
         DefaultEndpointRegistry reg = (DefaultEndpointRegistry) ctx.getEndpointRegistry();
 
+        // creates a new endpoint after context is stated and therefore dynamic
         ctx.getEndpoint("direct:error");
         assertTrue(reg.isDynamic("direct:error"));
 
+        ctx.removeEndpoints("direct:error");
+
+        // mark we are setting up routes (done = false)
         ctx.setupRoutes(false);
         ctx.getEndpoint("direct:error");
         assertTrue(reg.isStatic("direct:error"));
     }
 
+    @Test
+    public void testMigrationRoute() throws Exception {
+        DefaultCamelContext ctx = new DefaultCamelContext();
+        ctx.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                errorHandler(deadLetterChannel("direct:error")
+                        .maximumRedeliveries(2)
+                        .redeliveryDelay(0));
+
+                from("direct:error")
+                        .routeId("error")
+                        .errorHandler(deadLetterChannel("log:dead?level=ERROR"))
+                        .to("mock:error")
+                        .to("file:error");
+            }
+        });
+        ctx.start();
+
+        EndpointRegistry reg = ctx.getEndpointRegistry();
+        assertTrue(reg.isStatic("direct:error"));
+        assertTrue(reg.isStatic("mock:error"));
+        assertTrue(reg.isStatic("file:error"));
+    }
+
 }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointRegistryTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointRegistryTest.java
index 6d8727c..055df716 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointRegistryTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointRegistryTest.java
@@ -72,7 +72,7 @@ public class ManagedEndpointRegistryTest extends ManagementTestSupport {
 
         String source = (String) mbeanServer.getAttribute(on, "Source");
         assertTrue(source.startsWith("EndpointRegistry"));
-        assertTrue(source.endsWith("capacity: 1000"));
+        assertTrue(source.endsWith("capacity: 1000]"));
 
         TabularData data = (TabularData) mbeanServer.invoke(on, "listEndpoints", null, null);
         assertEquals(3, data.size());
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
index b3049e1..290211a 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
@@ -70,14 +70,14 @@ public class ManagedTransformerRegistryTest extends ManagementTestSupport {
         assertEquals(2, current.intValue());
 
         current = (Integer) mbeanServer.getAttribute(on, "StaticSize");
-        assertEquals(0, current.intValue());
+        assertEquals(2, current.intValue());
 
         current = (Integer) mbeanServer.getAttribute(on, "DynamicSize");
-        assertEquals(2, current.intValue());
+        assertEquals(0, current.intValue());
 
         String source = (String) mbeanServer.getAttribute(on, "Source");
         assertTrue(source.startsWith("TransformerRegistry"));
-        assertTrue(source.endsWith("capacity: 1000"));
+        assertTrue(source.endsWith("capacity: 1000]"));
 
         TabularData data = (TabularData) mbeanServer.invoke(on, "listTransformers", null, null);
         for (Object row : data.values()) {
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java
index a142b51..9735c60 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java
@@ -66,14 +66,14 @@ public class ManagedValidatorRegistryTest extends ManagementTestSupport {
         assertEquals(3, current.intValue());
 
         current = (Integer) mbeanServer.getAttribute(on, "StaticSize");
-        assertEquals(0, current.intValue());
+        assertEquals(3, current.intValue());
 
         current = (Integer) mbeanServer.getAttribute(on, "DynamicSize");
-        assertEquals(3, current.intValue());
+        assertEquals(0, current.intValue());
 
         String source = (String) mbeanServer.getAttribute(on, "Source");
         assertTrue(source.startsWith("ValidatorRegistry"));
-        assertTrue(source.endsWith("capacity: 1000"));
+        assertTrue(source.endsWith("capacity: 1000]"));
 
         TabularData data = (TabularData) mbeanServer.invoke(on, "listValidators", null, null);
         assertEquals(3, data.size());