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 ?
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.
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.
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
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
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?
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.
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.
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
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
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???
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.