*When I run this route heavily multithreaded camel route I am getting a
NullPointerException thrown in the CaseInsensitiveMap when it is copying the
exchanges for the multicast.  I am using version 2.9.2, though 2.10-SNAPSHOT
has the same issue.  I am doing this to reduce the latency and increase
throughput in this system.

Here is the fragment of the DSL which builds the route.
*
.....
processDefinition.split(genericTmcMappingProcessor)
    .parallelProcessing().timeout(timeout).threads(10, 20)
    .process(preDestinationProcessor).multicast()
       .parallelProcessing().timeout(timeout).threads(10,20)
    .to(destinationURIs);

*The CaseInsensitiveMap assembleKey method throws a NullPointerException on
the key.toString() as key is passed in null.*

    private static String assembleKey(Object key) {
*        String s = key.toString().toLowerCase();
*        if (s.startsWith("camel")) {
            // use intern String for headers which is Camel* headers
            // this reduces memory allocations needed for those common
headers
            s = s.intern();
        }
        return s;
    }


*The details of the issue is here in the Map.Entry anonymous class, where
the originalKeys.get(s) returns a null even though the originalKeys HashMap
actually has the data in it.  I know this because I can inspect it in the
debugger and it will return the proper value to me in the debugger.  
*
                Map.Entry<String, Object> view = new Map.Entry<String,
Object>() {
                    public String getKey() {
                        String s = entry.getKey();
                        // use the original key so we can preserve it
*                        return originalKeys.get(s);
*                    }

*I was able to make it more reliable by this ridiculous hack below, which
retries the originalKeys.get(s) up to 100 times, though this is not an
acceptable solution but an excercise to try to understand if this was a
multithreading issue. *

                    public synchronized String getKey() 
                    {
                        String s = entry.getKey();
                        String key = originalKeys.get(s);
                        
                        int count = 100;
                        while(count > 0 && key == null)
                        {
                           try
                           {
                              Thread.sleep(25);
                              key  = originalKeys.get(s);
                           }
                           catch(InterruptedException e)
                           {
                              e.printStackTrace();
                           }
                           finally
                           {
                              count--;
                           }
                        }

                        if(key == null)
                        {
                           System.out.println("get failed");
                        }
                        
                        return key;
                    }

*Here is the call stack when I set the breakpoint for
NullPointerExceptions.*

Daemon Thread [Camel (camel-1) thread #18 - Threads] (Suspended (exception
NullPointerException))  
        CaseInsensitiveMap.assembleKey(Object) line: 142        
        CaseInsensitiveMap.putAll(Map<String,?>) line: 97       
        GenericFileMessage<T>(MessageSupport).copyFrom(Message) line: 141       
        GenericFileMessage<T>(DefaultMessage).copyFrom(Message) line: 52        
        ExchangeHelper.copyResults(Exchange, Exchange) line: 249        
        Splitter(MulticastProcessor).doDone(Exchange, Exchange, AsyncCallback,
boolean, boolean) line: 749     
        Splitter(MulticastProcessor).process(Exchange, AsyncCallback) line: 238 
        Splitter.process(Exchange, AsyncCallback) line: 97      
        AsyncProcessorHelper.process(AsyncProcessor, Exchange, AsyncCallback) 
line:
73      
        InstrumentationProcessor(DelegateAsyncProcessor).processNext(Exchange,
AsyncCallback) line: 
..........

*I believe this to be an issue with the CaseInsensitiveMap not being
threadsafe.  Shouldn't a threadsafe version be implemented using
ConcurrentHashmaps and syncronization?

I have not been able to get a simple case together to show this issue, I
will work on that in the next few days.
*

--
View this message in context: 
http://camel.465427.n5.nabble.com/Possible-threading-issue-tp5714069.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply via email to