camel-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Krzysztof Mackowiak (JIRA)" <j...@apache.org>
Subject [jira] [Created] (CAMEL-8199) Race condition in JmsProducer for request/response messaging causing nondeterministic setting body to null.
Date Tue, 30 Dec 2014 13:58:13 GMT
Krzysztof Mackowiak created CAMEL-8199:
------------------------------------------

             Summary: Race condition in JmsProducer for request/response messaging causing
nondeterministic setting body to null.
                 Key: CAMEL-8199
                 URL: https://issues.apache.org/jira/browse/CAMEL-8199
             Project: Camel
          Issue Type: Bug
          Components: camel-jms
    Affects Versions: 2.14.0
            Reporter: Krzysztof Mackowiak


In my team we have noticed that there is a race condition problem in JmsProducer class for
request/response messaging. It causes that sometimes (nondeterministically) body of a response
message is changed to null. It can happen when JMS response is received very fast (we use
in-memory ActiveMQ with VM transport and no persistence) under heavy load.

It looks that there is a problem in JmsProducer class in processInOut(exchange, callback)
method.

{code}
    protected boolean processInOut(final Exchange exchange, final AsyncCallback callback)
{
        …
        doSend(true, destinationName, destination, messageCreator, messageSentCallback);
        // after sending then set the OUT message id to the JMSMessageID so its identical
        setMessageId(exchange);
        // continue routing asynchronously (reply will be processed async when its received)
        return false;
    }

...
    protected void setMessageId(Exchange exchange) {
        if (exchange.hasOut()) {
            JmsMessage out = exchange.getOut(JmsMessage.class);
            try {
                if (out != null && out.getJmsMessage() != null) {
                    out.setMessageId(out.getJmsMessage().getJMSMessageID());
                }
            } catch (JMSException e) {
                LOG.warn("Unable to retrieve JMSMessageID from outgoing JMS Message and set
it into Camel's MessageId", e);
            }
        }
    }
{code}

The problem is caused by invoking setMessageId(...) method after doSend(...). Method doSend(...)
is sending JMS request message and causes that another thread is used to handle JMS reply
message. This leads to a situation that 2 different threads can operate on the same exchange
(which is not synchronized at all) at the same time:
1) original thread in which processInOut(...) method was called,
2) separate thread from JMS component for handling JMS response.

In our case there it was happening sometimes that setMessageId(...) was invoked at the same
time as PipelineHelper.createNextMessage(exchange) method:
{code}
    public static Exchange createNextExchange(Exchange previousExchange) {
        Exchange answer = previousExchange;
        // now lets set the input of the next exchange to the output of the
        // previous message if it is not null
        if (answer.hasOut()) {
            answer.setIn(answer.getOut());
            answer.setOut(null);
        }
        return answer;
    }
{code}
It caused that body of response message was lost (set to null).


It looks for me that calling setMessageId(...) at the end of processInOut(...) method is redundant
and this logic should be executed when JMS reply message is handled.

I've attached a patch where invokation of setMessageId(...) is removed.
I've checked that it doesn't break any test for camel-jms component.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message