Loose coupling ..

Posted by jmls on 25-Jul-2011 15:26

I am trying to get two apps that currently communicate via webspeed using a CURL command to use sonic / ApacheMQ / JMS and therefore move to a loose coupling model.

However. I have a problem.

Currently System A sends a post to System B , system B does some processing and returns some data

in the loose coupling, System A posts a message, and moves to the next step, which to listen for a specific message. System B is notified of Systems A's message, does it's processing and sends a new response message back to System A via the message broker.

The trouble I have is that System B processes the message so damned fast (great code, of course ... ) and sends the response *before* System A gets a chance to listen for the message. So it sits there, and eventually times out

Has anyone worked out a solution to this problem ?

All Replies

Posted by Admin on 25-Jul-2011 15:51

The trouble I have is that System B processes the message so damned fast (great code, of course ... ) and sends the response before System A gets a chance to listen for the message. So it sits there, and eventually times out

 

I might not understand this properly, but doesn’t the Q in MQ stand for a queue. If you send messages to a queue, rather than a topic, the message stays there until someone is ready to listen. Must say, I never used Apache MQ a lot so far (want to change that any time soon), but that's what it would be in Sonic MQ and that's my understanding of JMS.

Posted by Thomas Mercer-Hursh on 25-Jul-2011 15:58

My first thought is that the problem is actually the configuration of your transport since, even if it were true that the message could be sent, received, decoded, processed, and a response sent before the other process had time to start listening, it should still pick up the message.  Think, for example, of the case where the link between two systems is down and one system sends a bunch of messages which just get stored because there is nowhere for them to go to.  When the link comes back up, they should all get delivered.

So, the first thing you might do is to put in some pauses so that you can keep the system from returning the message until you have confirmed the other one is ready and see whether the message gets through then.  I'm guessing it doesn't and there is some configuration issue which is keeping the message from being delivered.

You could, of course, have more than one service on the first machine so that the listener was already listening before the sender sent the first message, but I don't think that is your problem.

Posted by jmls on 25-Jul-2011 16:01

I think for that you need a durable subscription.

A queue = a message for a consumer. If you have more than 1 consumer

of a queue , a message is sent to one subscriber, and then next next

message is sent to the next subscriber, round-robin style.

A topic = a message for multiple subscribers. Each message is sent to

each subscriber

the important thing is that unless you have a durable subscription,

when you connect, you don't get previous messages.

Now, the problem that I have is that I have to use REST for the

messages from System A. IOW, the call waits for a message, so I can't

create a durable subscription first

Posted by jmls on 25-Jul-2011 16:06

See my response to Mike for the problem I have with durable subscriptions.

I think that the problem is as described, because if I send a second

message from the command line (dos , for example) System A receives

that message and carries on. So, it misses the first message, but not

the second.

If I put a "pause 1 no-message" in System B before I send the message,

it does indeed work.

I can't have more than one service on System A , unfortunately. It is

a step-by-step process. Line1. Line2. Line3.

On 25 July 2011 21:58, Thomas Mercer-Hursh

Posted by Tim Kuehn on 26-Jul-2011 07:48

jmls wrote:

The trouble I have is that System B processes the message so damned fast (great code, of course ... ) and sends the response *before* System A gets a chance to listen for the message. So it sits there, and eventually times out

How can "B" send a message if "A" isn't listening for it yet? "B" should get some kind of 'confirmation of delivery' before it moves on to something, no?

Posted by jmls on 26-Jul-2011 09:36

B sends a message to the queue because it has finished the processing

it needs to do.

"Hey I'm done".

The problem is that A hasn't reached the point where it subscribes to

the queue that B sends to.

Posted by maximmonin on 27-Jul-2011 02:34

Durable subscription to topic means that client can be offline or online.

If client is offline then message will be stored in topic and MQ will keep it until client connects and gets it (sending confirmation if needed).

Messages should have persistent flag.

Posted by Admin on 27-Jul-2011 03:56

jmls wrote:

The problem is that A hasn't reached the point where it subscribes to

the queue that B sends to.

Well, the obviously question will be... why don't you subscribe to that topic (right?) before sending the triggering message to the system B?

Having a subscription active does not mean that you actually block listening for a message, depending on your need you can of course block at some point for a message or just process it when it pop-in... most probably your issue has nothing to do with MQ, JMS, topic but with the 'adapter' you use and the way you use it

Posted by jmls on 27-Jul-2011 04:26

that is exactly the problem. System A does not have a native jms

client, so we are having to use the ApacheMQ REST interface with curl.

Which, of course, blocks whilst waiting for the message.

So, I can't subscribe to QueueX before sending the message .

Unless there is a way of subscribing to queue X without blocking, and

then joining the queue after. I am looking at guid and clientid to see

if I can keep a session open between requests

Posted by Admin on 27-Jul-2011 04:42

jmls wrote:

that is exactly the problem. System A does not have a native jms

client, so we are having to use the ApacheMQ REST interface with curl.

Which, of course, blocks whilst waiting for the message.

hmm, didn't used the REST interface so far but it looks like you have to keep the session open between request or you have to use the same clientId or it will look like a new consumer on each request... don't know exactly what is the prefetch size all about but you might also try to set that to 1 as mentioned on apachemq rest page.

what is not clear is that there is an unsubscribe action that can be used if clientId is employed, does this means that when using clientId a durable subscription is made on first consume request???

Posted by maximmonin on 27-Jul-2011 04:49

Appache MQ web interface has button "Create durable subscription" for this task.

Client subscription is just identification as durable subscriber and tells MQ to push mesages from topic to client.

This thread is closed