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 <claus.ib...@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());