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 2017/07/05 07:28:35 UTC
[2/8] camel git commit: CAMEL-11321: Start Camel faster by letting
LRUCache warmup concurrently as that takes up 150 millis or more.
CAMEL-11321: Start Camel faster by letting LRUCache warmup concurrently as that takes up 150 millis or more.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f8e68bac
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f8e68bac
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f8e68bac
Branch: refs/heads/master
Commit: f8e68bac676d9a1a43f1f2744aa467cba77ec169
Parents: f647c22
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Jul 4 15:46:17 2017 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Jul 5 09:28:22 2017 +0200
----------------------------------------------------------------------
.../apache/camel/impl/DefaultCamelContext.java | 13 +++-
.../impl/DefaultPackageScanClassResolver.java | 4 +-
.../camel/impl/ProvisionalEndpointRegistry.java | 74 ++++++++++++++++++++
.../management/DefaultManagementAgent.java | 10 ++-
.../DefaultManagementMBeanAssembler.java | 13 +++-
.../camel/management/MBeanInfoAssembler.java | 6 +-
.../org/apache/camel/util/LRUCacheFactory.java | 59 ++++++++++++++++
.../org/apache/camel/ContextTestSupport.java | 2 +
8 files changed, 173 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index ef50425..3ebad6d 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -178,6 +178,7 @@ import org.apache.camel.util.EventHelper;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.IntrospectionSupport;
import org.apache.camel.util.JsonSchemaHelper;
+import org.apache.camel.util.LRUCacheFactory;
import org.apache.camel.util.LoadPropertiesException;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.OrderedComparator;
@@ -316,10 +317,18 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
* Use one of the other constructors to force use an explicit registry / JNDI.
*/
public DefaultCamelContext() {
+ boolean warmUp = "true".equalsIgnoreCase(System.getProperty("CamelWarmUpLRUCacheFactory", "true"));
+ if (warmUp) {
+ // warm-up LRUCache which happens in a background test, which can speedup starting Camel
+ // as the warm-up can run concurrently with starting up Camel and the runtime container Camel may be running inside
+ LRUCacheFactory.warmUp();
+ }
+
this.executorServiceManager = new DefaultExecutorServiceManager(this);
- // create endpoint registry at first since end users may access endpoints before CamelContext is started
- this.endpoints = new DefaultEndpointRegistry(this);
+ // create a provisional (temporary) endpoint registry at first since end users may access endpoints before CamelContext is started
+ // we will later transfer the endpoints to the actual DefaultEndpointRegistry later, but we do this to starup Camel faster.
+ this.endpoints = new ProvisionalEndpointRegistry();
// add the defer service startup listener
this.startupListeners.add(deferStartupListener);
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/impl/DefaultPackageScanClassResolver.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultPackageScanClassResolver.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultPackageScanClassResolver.java
index a9074f8..13dfa3d 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultPackageScanClassResolver.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultPackageScanClassResolver.java
@@ -47,7 +47,7 @@ import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.PackageScanFilter;
import org.apache.camel.support.ServiceSupport;
import org.apache.camel.util.IOHelper;
-import org.apache.camel.util.LRUSoftCache;
+import org.apache.camel.util.LRUCacheFactory;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -510,7 +510,7 @@ public class DefaultPackageScanClassResolver extends ServiceSupport implements P
protected void doStart() throws Exception {
if (jarCache == null) {
// use a JAR cache to speed up scanning JARs, but let it be soft referenced so it can claim the data when memory is needed
- jarCache = new LRUSoftCache<String, List<String>>(1000);
+ jarCache = LRUCacheFactory.newLRUCache(1000);
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/impl/ProvisionalEndpointRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ProvisionalEndpointRegistry.java b/camel-core/src/main/java/org/apache/camel/impl/ProvisionalEndpointRegistry.java
new file mode 100644
index 0000000..0600066
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/ProvisionalEndpointRegistry.java
@@ -0,0 +1,74 @@
+/**
+ * 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.camel.impl;
+
+import java.util.HashMap;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.EndpointRegistry;
+
+/**
+ * A provisional (temporary) {@link EndpointRegistry} that is only used during startup of Apache Camel to
+ * make starting Camel faster while {@link org.apache.camel.util.LRUCacheFactory} is warming up etc.
+ */
+class ProvisionalEndpointRegistry extends HashMap<EndpointKey, Endpoint> implements EndpointRegistry<EndpointKey> {
+
+ @Override
+ public void start() throws Exception {
+ // noop
+ }
+
+ @Override
+ public void stop() throws Exception {
+ // noop
+ }
+
+ @Override
+ public int staticSize() {
+ return 0;
+ }
+
+ @Override
+ public int dynamicSize() {
+ return 0;
+ }
+
+ @Override
+ public int getMaximumCacheSize() {
+ return 0;
+ }
+
+ @Override
+ public void purge() {
+ // noop
+ }
+
+ @Override
+ public boolean isStatic(String key) {
+ return false;
+ }
+
+ @Override
+ public boolean isDynamic(String key) {
+ return false;
+ }
+
+ @Override
+ public void cleanUp() {
+ // noop
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
index 7f6449b..d3f7280 100644
--- a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
+++ b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
@@ -49,6 +49,7 @@ import org.apache.camel.spi.ManagementMBeanAssembler;
import org.apache.camel.support.ServiceSupport;
import org.apache.camel.util.InetAddressUtil;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,6 +67,8 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
private CamelContext camelContext;
private MBeanServer server;
+ private ManagementMBeanAssembler assembler;
+
// need a name -> actual name mapping as some servers changes the names (such as WebSphere)
private final ConcurrentMap<ObjectName, ObjectName> mbeansRegistered = new ConcurrentHashMap<ObjectName, ObjectName>();
private JMXConnectorServer cs;
@@ -339,7 +342,6 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
registerMBeanWithServer(obj, name, forceRegistration);
} catch (NotCompliantMBeanException e) {
// If this is not a "normal" MBean, then try to deploy it using JMX annotations
- ManagementMBeanAssembler assembler = camelContext.getManagementMBeanAssembler();
ObjectHelper.notNull(assembler, "ManagementMBeanAssembler", camelContext);
Object mbean = assembler.assemble(server, obj, name);
if (mbean != null) {
@@ -386,6 +388,10 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
createMBeanServer();
}
+ // ensure assembler is started
+ assembler = camelContext.getManagementMBeanAssembler();
+ ServiceHelper.startService(assembler);
+
LOG.debug("Starting JMX agent on server: {}", getMBeanServer());
}
@@ -432,6 +438,8 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
+ " exceptions caught while unregistering MBeans during stop operation."
+ " See INFO log for details.");
}
+
+ ServiceHelper.stopService(assembler);
}
private void registerMBeanWithServer(Object obj, ObjectName name, boolean forceRegistration)
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java
index a28bcbb..dc8f970 100644
--- a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java
+++ b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementMBeanAssembler.java
@@ -29,7 +29,9 @@ import org.apache.camel.api.management.ManagedInstance;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.api.management.NotificationSenderAware;
import org.apache.camel.spi.ManagementMBeanAssembler;
+import org.apache.camel.support.ServiceSupport;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,7 +42,7 @@ import org.slf4j.LoggerFactory;
*
* @version
*/
-public class DefaultManagementMBeanAssembler implements ManagementMBeanAssembler {
+public class DefaultManagementMBeanAssembler extends ServiceSupport implements ManagementMBeanAssembler {
private static final Logger LOG = LoggerFactory.getLogger(DefaultManagementMBeanAssembler.class);
protected final MBeanInfoAssembler assembler;
protected final CamelContext camelContext;
@@ -114,4 +116,13 @@ public class DefaultManagementMBeanAssembler implements ManagementMBeanAssembler
return mbean;
}
+ @Override
+ protected void doStart() throws Exception {
+ ServiceHelper.startService(assembler);
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ ServiceHelper.stopService(assembler);
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java b/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
index 09cbf89..4dfb0b7 100644
--- a/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
+++ b/camel-core/src/main/java/org/apache/camel/management/MBeanInfoAssembler.java
@@ -40,6 +40,7 @@ import org.apache.camel.api.management.ManagedOperation;
import org.apache.camel.api.management.ManagedResource;
import org.apache.camel.util.IntrospectionSupport;
import org.apache.camel.util.LRUCache;
+import org.apache.camel.util.LRUCacheFactory;
import org.apache.camel.util.LRUWeakCache;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
@@ -57,7 +58,7 @@ public class MBeanInfoAssembler implements Service {
// use a cache to speedup gathering JMX MBeanInfo for known classes
// use a weak cache as we dont want the cache to keep around as it reference classes
// which could prevent classloader to unload classes if being referenced from this cache
- private final LRUCache<Class<?>, MBeanAttributesAndOperations> cache = new LRUWeakCache<Class<?>, MBeanAttributesAndOperations>(1000);
+ private LRUCache<Class<?>, MBeanAttributesAndOperations> cache;
public MBeanInfoAssembler() {
}
@@ -67,8 +68,9 @@ public class MBeanInfoAssembler implements Service {
}
@Override
+ @SuppressWarnings("unchecked")
public void start() throws Exception {
- // noop
+ cache = LRUCacheFactory.newLRUWeakCache(1000);
}
@Override
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/main/java/org/apache/camel/util/LRUCacheFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/LRUCacheFactory.java b/camel-core/src/main/java/org/apache/camel/util/LRUCacheFactory.java
new file mode 100644
index 0000000..59b4620
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/util/LRUCacheFactory.java
@@ -0,0 +1,59 @@
+/**
+ * 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.camel.util;
+
+import org.apache.camel.util.concurrent.ThreadHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory to create {@link LRUCache} instances.
+ */
+public final class LRUCacheFactory {
+
+ // TODO: use LRUCacheFactory in other places to create the LRUCaches
+
+ private static final Logger LOG = LoggerFactory.getLogger(LRUCacheFactory.class);
+
+ private LRUCacheFactory() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void warmUp() {
+ // create a dummy map in a separate thread to warmup the Caffeine cache
+ // as we want to do this as early as possible while creating CamelContext
+ // so when Camel is starting up its faster as the Caffeine cache has been initialized
+ Runnable warmup = () -> {
+ LOG.debug("Warming up LRUCache ...");
+ newLRUCache(16);
+ LOG.debug("Warming up LRUCache complete");
+ };
+
+ String threadName = ThreadHelper.resolveThreadName(null, "LRUCacheFactory");
+
+ Thread thread = new Thread(warmup, threadName);
+ thread.start();
+ }
+
+ public static LRUCache newLRUCache(int maximumCacheSize) {
+ return new LRUCache(maximumCacheSize);
+ }
+
+ public static LRUWeakCache newLRUWeakCache(int maximumCacheSize) {
+ return new LRUWeakCache(maximumCacheSize);
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f8e68bac/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java b/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
index e4544ce..8b9dfe4 100644
--- a/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
+++ b/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
@@ -83,6 +83,8 @@ public abstract class ContextTestSupport extends TestSupport {
protected void setUp() throws Exception {
// make SEDA testing faster
System.setProperty("CamelSedaPollTimeout", "10");
+ // no need to warm-up when testing camel-core as that creates a new thread per CamelContext and Caffiene is initialized only once
+ System.setProperty("CamelWarmUpLRUCacheFactory", "false");
if (!useJmx()) {
disableJMX();