Yes, I agree with that, reason why Registries that use caches *are* and
should stay as Services. The PropertyEditorTypeConverter in particular
doesn't need to be a Service, but the EndpointRegisty, ConsumerCache and
ProducerCache should be and are Services.
So you are correct about not leaving memory leaks, etc. Owners of caches
that hold Service(s) should and do shut them down before the cache
clear() since that's not the job of the cache itself (plus caches may
not hold Services in which case all the iteration over, dunno, hundreds,
thousands of object to check for (item instanceof Service) is kinda
useless anyway. Services are something that have a life cycle, the
LRUCache is a handy data structure. All in all I was quite careful about
my changes, I hope I didn't miss anything. I am sure that if anybody
spots something he'll point it out and we'll fix it. Needless to say,
all tests pass after my changes and I am fairly comfortable with the fix.
Cheers,
Hadrian
On 08/31/2011 03:55 PM, Claus Ibsen wrote:
I wonder if there wont be a problem when you shutdown camel, or run
Camel in a hot deployment environment.
As before the service would ensure start|stop callbacks, where we
could clear the caches when stopping.
That is now gone, which means we can just hope the GC eventually will
be able to reclaim the objects.
So I suggest to use Service for classes that has caches or any map
store which can hold possible a lot of data.
Then being able to properly clean/stop those cachen when stopping
Camel is a good citizen to avoid eating memory or leaking in any way.
On Wed, Aug 31, 2011 at 7:10 PM,<hadr...@apache.org> wrote:
Author: hadrian
Date: Wed Aug 31 17:10:53 2011
New Revision: 1163705
URL: http://svn.apache.org/viewvc?rev=1163705&view=rev
Log:
CAMEL-4392. Fix side effect of LRUCache not a service.
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/PropertyEditorTypeConverter.java
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanComponentCustomCreateEndpointTest.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/PropertyEditorTypeConverter.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/PropertyEditorTypeConverter.java?rev=1163705&r1=1163704&r2=1163705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/PropertyEditorTypeConverter.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/PropertyEditorTypeConverter.java
Wed Aug 31 17:10:53 2011
@@ -22,11 +22,9 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.camel.Exchange;
-import org.apache.camel.Service;
import org.apache.camel.TypeConverter;
import org.apache.camel.util.LRUSoftCache;
import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,14 +34,14 @@ import org.slf4j.LoggerFactory;
*
* @version
*/
-public class PropertyEditorTypeConverter implements TypeConverter, Service {
+public class PropertyEditorTypeConverter implements TypeConverter {
private static final Logger LOG =
LoggerFactory.getLogger(PropertyEditorTypeConverter.class);
// use a soft bound cache to avoid using too much memory in case a lot of
different classes
// is being converted to string
- private final Map<Class, Class> misses = new LRUSoftCache<Class,
Class>(1000);
+ private final Map<Class<?>, Class<?>> misses = new LRUSoftCache<Class<?>,
Class<?>>(1000);
// we don't anticipate so many property editors so we have unbounded map
- private final Map<Class, PropertyEditor> cache = new HashMap<Class,
PropertyEditor>();
+ private final Map<Class<?>, PropertyEditor> cache = new HashMap<Class<?>,
PropertyEditor>();
public<T> T convertTo(Class<T> type, Object value) {
// We can't convert null values since we can't figure out a property
@@ -58,14 +56,14 @@ public class PropertyEditorTypeConverter
return ObjectHelper.cast(type, value);
}
- Class key = type;
+ Class<?> key = type;
PropertyEditor editor = lookupEditor(key);
if (editor != null) {
editor.setAsText(value.toString());
return ObjectHelper.cast(type, editor.getValue());
}
} else if (type == String.class) {
- Class key = value.getClass();
+ Class<?> key = value.getClass();
PropertyEditor editor = lookupEditor(key);
if (editor != null) {
editor.setValue(value);
@@ -76,7 +74,7 @@ public class PropertyEditorTypeConverter
return null;
}
- private PropertyEditor lookupEditor(Class type) {
+ private PropertyEditor lookupEditor(Class<?> type) {
// check misses first
if (misses.containsKey(type)) {
LOG.trace("No previously found property editor for type: {}",
type);
@@ -115,14 +113,4 @@ public class PropertyEditorTypeConverter
public<T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object
value) {
return convertTo(type, value);
}
-
- public void start() throws Exception {
- ServiceHelper.startService(misses);
- }
-
- public void stop() throws Exception {
- cache.clear();
- ServiceHelper.stopService(misses);
- }
-
}
Modified:
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanComponentCustomCreateEndpointTest.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanComponentCustomCreateEndpointTest.java?rev=1163705&r1=1163704&r2=1163705&view=diff
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanComponentCustomCreateEndpointTest.java
(original)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanComponentCustomCreateEndpointTest.java
Wed Aug 31 17:10:53 2011
@@ -47,11 +47,11 @@ public class BeanComponentCustomCreateEn
public void testCreateEndpointUri() throws Exception {
BeanComponent bc = context.getComponent("bean", BeanComponent.class);
- ProcessorEndpoint pe = bc.createEndpoint(new MyFooBean(), "cheese");
+ ProcessorEndpoint pe = bc.createEndpoint(new MyFooBean(),
"bean:cheese");
assertNotNull(pe);
String uri = pe.getEndpointUri();
- assertEquals("cheese", uri);
+ assertEquals("bean:cheese", uri);
Producer producer = pe.createProducer();
Exchange exchange = producer.createExchange();