You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by ee7arh <an...@2e-systems.com> on 2008/09/27 12:33:00 UTC

Using ExchangePattern.InOut blocks request queue

Hi,

I wonder if anyone can point out where I'm going wrong, maybe I'm missing
something conceptually.

I have a multi-threaded client application which wants to do
request/response with a camel server application and I am trying to use the
ExchangePattern.InOut when calling the sendBody() on the Producer.

The behaviour I am observing is that if say 3 client threads try to call the
sendBody() method at the same time (i.e. try to send a request to the server
and wait for a response), only 1 client thread at a time will be able to do
some processing and the others effectively block until the processing of the
one in front finishes. So rather than processing taking place in parallel,
it takes place sequentially one after the other.

I know that sendBody() with the ExchangePattern.InOut pattern is a
synchronous call, that's fine and how I want it. But I am surprised that the
queue blocks when attempting multi threading because the JMS
request/response pattern described in ActiveMQ makes use of temporary
destinations to send responses back matching back using correlationIds.

Could anybody confirm if my assumptions are correct and if so, what could be
the problem?


-- 
View this message in context: http://www.nabble.com/Using-ExchangePattern.InOut-blocks-request-queue-tp19701558s22882p19701558.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Using ExchangePattern.InOut blocks request queue

Posted by James Strachan <ja...@gmail.com>.
2008/9/29 James Strachan <ja...@gmail.com>:
> 2008/9/29 ee7arh <an...@2e-systems.com>:
>>
>> Hi Willem,
>>
>> Thanks for your answer.
>>
>> I've actually solved the issue now using Spring Remoting but will explain in
>> more detail my original dilema since it took us a lot of hardwork and
>> searching to "stumble upon" the solution ;)
>>
>> Perhaps I should first clarify that what I was trying to achieve was to
>> replace RMI with Camel [using JMS underneath] within my application. I had a
>> multi threaded client application one 1 side which sent requests to an RMI
>> server application on the other side. Standard client/server stuff, sort of
>> like a WebServer where requests are in effect able to be processed by the
>> server in parallel (although each request is atomic).
>>
>> So instead of starting up an RMI server, I replaced this with Camel. My
>> routes were configured something like this:
>>
>> from("jms:queue:myqueue").to("bean:requestProcessor?methodName=processRequest");
>>
>> In my former RMI "Impl" class which actually did the service processing on
>> the server side, instead of extending UnicastRemoteObject, I now just added
>> the following annotation at the top of the class:
>>
>> @Service(value = "requestProcessor")
>>
>> And within that class I had a method called "processRequest()".
>>
>> The behaviour I wanted was that whenever a client thread wanted the server
>> to process a service request, it would use the ExchangePattern.InOut when
>> calling sendBody() like so:
>>
>> myResponseObject = (MyResponse)camelTemplate.sendBody("jms:queue:myqueue",
>> ExchangePattern.InOut, myReqObject);
>>
>> This seemed to work fine but I noticed that the server would process only 1
>> client request at a time. I guess this is because there is actually only a
>> single consumer on the server side reading off the underlying JMS queue.
>
> Yeah - you can enable more concurrent processing of the requests by
> configuring your JMS component - or via the URI
>
> See
>
> http://activemq.apache.org/camel/jms.html
>
> e.g.
>
> from("jms:queue:myqueue?concurrentConsumers=50").to("bean:requestProcessor?methodName=processRequest");

I've added this to the FAQ
http://cwiki.apache.org/CAMEL/why-does-my-jms-route-only-consume-one-message-at-once.html

-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://open.iona.com

Re: Using ExchangePattern.InOut blocks request queue

Posted by James Strachan <ja...@gmail.com>.
2008/9/29 ee7arh <an...@2e-systems.com>:
>
> Hi Willem,
>
> Thanks for your answer.
>
> I've actually solved the issue now using Spring Remoting but will explain in
> more detail my original dilema since it took us a lot of hardwork and
> searching to "stumble upon" the solution ;)
>
> Perhaps I should first clarify that what I was trying to achieve was to
> replace RMI with Camel [using JMS underneath] within my application. I had a
> multi threaded client application one 1 side which sent requests to an RMI
> server application on the other side. Standard client/server stuff, sort of
> like a WebServer where requests are in effect able to be processed by the
> server in parallel (although each request is atomic).
>
> So instead of starting up an RMI server, I replaced this with Camel. My
> routes were configured something like this:
>
> from("jms:queue:myqueue").to("bean:requestProcessor?methodName=processRequest");
>
> In my former RMI "Impl" class which actually did the service processing on
> the server side, instead of extending UnicastRemoteObject, I now just added
> the following annotation at the top of the class:
>
> @Service(value = "requestProcessor")
>
> And within that class I had a method called "processRequest()".
>
> The behaviour I wanted was that whenever a client thread wanted the server
> to process a service request, it would use the ExchangePattern.InOut when
> calling sendBody() like so:
>
> myResponseObject = (MyResponse)camelTemplate.sendBody("jms:queue:myqueue",
> ExchangePattern.InOut, myReqObject);
>
> This seemed to work fine but I noticed that the server would process only 1
> client request at a time. I guess this is because there is actually only a
> single consumer on the server side reading off the underlying JMS queue.

Yeah - you can enable more concurrent processing of the requests by
configuring your JMS component - or via the URI

See

http://activemq.apache.org/camel/jms.html

e.g.

from("jms:queue:myqueue?concurrentConsumers=50").to("bean:requestProcessor?methodName=processRequest");


> To acheive true Request/Response, I have turned to "Spring Remoting" to get
> this working (which it now does having followed the examples provided - link
> below [2] ).
>
> Do you think this is the right strategy in the end or was there something I
> missed along the way which would I mean I can use pure Camel?
>
> [2] http://activemq.apache.org/camel/spring-remoting.html

Spring Remoting is really just a POJO facade above the pure Camel
underneath; so everything you can do with Spring Remoting should work
with pure Camel too. Though I favour hiding all middleware code where
possible...
http://activemq.apache.org/camel/hiding-middleware.html

so using Spring Remoting is a good thing IMHO as it hides both the JMS
and Camel APIs from your business logic etc.

-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://open.iona.com

Re: Using ExchangePattern.InOut blocks request queue

Posted by ee7arh <an...@2e-systems.com>.
Hi Willem,

Thanks for your answer.

I've actually solved the issue now using Spring Remoting but will explain in
more detail my original dilema since it took us a lot of hardwork and
searching to "stumble upon" the solution ;)

Perhaps I should first clarify that what I was trying to achieve was to
replace RMI with Camel [using JMS underneath] within my application. I had a
multi threaded client application one 1 side which sent requests to an RMI
server application on the other side. Standard client/server stuff, sort of
like a WebServer where requests are in effect able to be processed by the
server in parallel (although each request is atomic).

So instead of starting up an RMI server, I replaced this with Camel. My
routes were configured something like this:

from("jms:queue:myqueue").to("bean:requestProcessor?methodName=processRequest");

In my former RMI "Impl" class which actually did the service processing on
the server side, instead of extending UnicastRemoteObject, I now just added
the following annotation at the top of the class:

@Service(value = "requestProcessor")

And within that class I had a method called "processRequest()".

The behaviour I wanted was that whenever a client thread wanted the server
to process a service request, it would use the ExchangePattern.InOut when
calling sendBody() like so:

myResponseObject = (MyResponse)camelTemplate.sendBody("jms:queue:myqueue",
ExchangePattern.InOut, myReqObject);

This seemed to work fine but I noticed that the server would process only 1
client request at a time. I guess this is because there is actually only a
single consumer on the server side reading off the underlying JMS queue.

To acheive true Request/Response, I have turned to "Spring Remoting" to get
this working (which it now does having followed the examples provided - link
below [2] ). 

Do you think this is the right strategy in the end or was there something I
missed along the way which would I mean I can use pure Camel?

[2] http://activemq.apache.org/camel/spring-remoting.html

Regards
Andrew


willem.jiang wrote:
> 
> Hi
> 
> Can you show me you route configure file and your client request sending 
> code ?
> I checked the ProducerTemplate code , there is no any synchronized token.
> According the wiki page[1], the JMS component should support the 
> parallel processing.
> 
> [1] http://cwiki.apache.org/CAMEL/parallel-processing-and-ordering.html
> 
> Willem
> 
> 
> ee7arh wrote:
>> Hi,
>>
>> I wonder if anyone can point out where I'm going wrong, maybe I'm missing
>> something conceptually.
>>
>> I have a multi-threaded client application which wants to do
>> request/response with a camel server application and I am trying to use
>> the
>> ExchangePattern.InOut when calling the sendBody() on the Producer.
>>
>> The behaviour I am observing is that if say 3 client threads try to call
>> the
>> sendBody() method at the same time (i.e. try to send a request to the
>> server
>> and wait for a response), only 1 client thread at a time will be able to
>> do
>> some processing and the others effectively block until the processing of
>> the
>> one in front finishes. So rather than processing taking place in
>> parallel,
>> it takes place sequentially one after the other.
>>
>> I know that sendBody() with the ExchangePattern.InOut pattern is a
>> synchronous call, that's fine and how I want it. But I am surprised that
>> the
>> queue blocks when attempting multi threading because the JMS
>> request/response pattern described in ActiveMQ makes use of temporary
>> destinations to send responses back matching back using correlationIds.
>>
>> Could anybody confirm if my assumptions are correct and if so, what could
>> be
>> the problem?
>>
>>
>>   
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Using-ExchangePattern.InOut-blocks-request-queue-tp19701558s22882p19724861.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Using ExchangePattern.InOut blocks request queue

Posted by Willem Jiang <wi...@gmail.com>.
Hi

Can you show me you route configure file and your client request sending 
code ?
I checked the ProducerTemplate code , there is no any synchronized token.
According the wiki page[1], the JMS component should support the 
parallel processing.

[1] http://cwiki.apache.org/CAMEL/parallel-processing-and-ordering.html

Willem


ee7arh wrote:
> Hi,
>
> I wonder if anyone can point out where I'm going wrong, maybe I'm missing
> something conceptually.
>
> I have a multi-threaded client application which wants to do
> request/response with a camel server application and I am trying to use the
> ExchangePattern.InOut when calling the sendBody() on the Producer.
>
> The behaviour I am observing is that if say 3 client threads try to call the
> sendBody() method at the same time (i.e. try to send a request to the server
> and wait for a response), only 1 client thread at a time will be able to do
> some processing and the others effectively block until the processing of the
> one in front finishes. So rather than processing taking place in parallel,
> it takes place sequentially one after the other.
>
> I know that sendBody() with the ExchangePattern.InOut pattern is a
> synchronous call, that's fine and how I want it. But I am surprised that the
> queue blocks when attempting multi threading because the JMS
> request/response pattern described in ActiveMQ makes use of temporary
> destinations to send responses back matching back using correlationIds.
>
> Could anybody confirm if my assumptions are correct and if so, what could be
> the problem?
>
>
>