Author |
Message
|
Danny12345 |
Posted: Tue Jan 08, 2008 10:54 am Post subject: use group id to identify client ? |
|
|
Newbie
Joined: 08 Jan 2008 Posts: 4
|
Hi. I'm new to MQ. I'm using the C++ API. My question is quite elementary. I want to set up a system whereby a variable (say N) number of instances of the same Client Application communicate with 1 Server Application. The clients submit (put) their requests into a predefined request queue and the Server replies by putting the replies into another predefined reply queue. So there's actually N clients, 1 Server and 2 queues. I read about the general (standard) approach to have the Server extract the MsgId from the request message and use this value to populate the CorrelId of the reply message. That works fine. My question is : given the fact that N clients will be "listening" to the same reply queue, how can I make sure that a given client only retrieves the replys to the requests he submitted ? True, the Client could memorize the MsgId's of his requests and then do a series of "get(msgId)" (match against CorrelId) but that seems slow, so is browsing the queue. Should I use the groupId to uniquely identify the Client and then do a "get(groupId)" ? Thank you |
|
Back to top |
|
 |
PeterPotkay |
Posted: Tue Jan 08, 2008 10:58 am Post subject: Re: use group id to identify client ? |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
Danny12345 wrote: |
True, the Client could memorize the MsgId's of his requests and then do a series of "get(msgId)" (match against CorrelId) but that seems slow, |
That is the correct way. It is the fastest way. Why would it be slow?
Of course nothing prevents one of the clients from grabbing any and all replies by specifying no Correl ID on its MQGET. To prevent that each client needs its own queue and via security methods you insure each client can only open its own reply queue(s). _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
Danny12345 |
Posted: Tue Jan 08, 2008 11:14 am Post subject: Re: use group id to identify client ? |
|
|
Newbie
Joined: 08 Jan 2008 Posts: 4
|
[quote="PeterPotkay"]
Danny12345 wrote: |
True, the Client could memorize the MsgId's of his requests and then do a series of "get(msgId)" (match against CorrelId) but that seems slow, |
That is the correct way. It is the fastest way. Why would it be slow?
Because a typical Client could have a variable number (say 50) "running" requests. This means that any Client constantly has to loop for every running msgId it has and issue a "get(msgId)". I seem to have understood that a get scans the queue sequentially (on NT ??), so this takes time. In our example, the queue is scanned 50 times by this one Client to (perhaps) find out there's no reply for him .. So I would prefer to scan the queue once : at the first encounter of any reply for this Client, I take it. Note that I am not interested in retrieving the reply in the same order as the initial request was submitted. Your opinion ? |
|
Back to top |
|
 |
tleichen |
Posted: Tue Jan 08, 2008 11:14 am Post subject: |
|
|
Yatiri
Joined: 11 Apr 2005 Posts: 663 Location: Center of the USA
|
I second Peter's comment. DON'T have multiple apps using the same queue, especially if you're new to MQ. It makes a simple problem much more difficult and opens up a real can of worms that you really don't want to get into.  _________________ IBM Certified MQSeries Specialist
IBM Certified MQSeries Developer |
|
Back to top |
|
 |
tleichen |
Posted: Tue Jan 08, 2008 11:22 am Post subject: Re: use group id to identify client ? |
|
|
Yatiri
Joined: 11 Apr 2005 Posts: 663 Location: Center of the USA
|
Danny12345 wrote: |
...Because a typical Client could have a variable number (say 50) "running" requests. This means that any Client constantly has to loop for every running msgId it has and issue a "get(msgId)". I seem to have understood that a get scans the queue sequentially (on NT ??), so this takes time. In our example, the queue is scanned 50 times by this one Client to (perhaps) find out there's no reply for him .. So I would prefer to scan the queue once : at the first encounter of any reply for this Client, I take it. Note that I am not interested in retrieving the reply in the same order as the initial request was submitted. Your opinion ? |
That is why you should avoid that design by having separate queues.  _________________ IBM Certified MQSeries Specialist
IBM Certified MQSeries Developer |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Jan 08, 2008 11:25 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Get with match doesn't scan the queue.
Even if the client doesn't do a get with match, it still needs to store the message id or etc. in order to match the reply with the given request, if it's going to have several requests pending at once.
If the client is going to have several requests pending at once, then it will need at least two connections to the queue manager open - one to put and one to get. You can only execute one MQ API operation over a connection at a time.
The fastest, most reliable, most standard mechanism is to use one connection for each request (and reuse connections in a pool) and have each connection do a get with wait and match based on CorrelID against the queue. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
LuisFer |
Posted: Tue Jan 08, 2008 11:27 am Post subject: Re: use group id to identify client ? |
|
|
 Partisan
Joined: 17 Aug 2002 Posts: 302
|
This sample is used for 2000 Clients over the same , Request Reply, Queues, are IMS Tx. The elapsed is 0,005 secs. no IMS time count.
Hope this help you
Code: |
GetMsgOpts.MatchOptions = MQMO_MATCH_CORREL_ID
+ MQMO_MATCH_MSG_ID;
MQPUT(Hcon,
Hobj,
&md,
&pmo,
msjlen,
mensaje,
&CompCode,
&Reason);
CheckCallResult("PUT:", CompCode, Reason);
pmdin = (PMQMD)malloc(sizeof(MQMD));
pgmoin = (PMQGMO)malloc(sizeof(MQGMO));
pmdin = (PMQMD)memcpy(pmdin, &MsgDesc, sizeof(MQMD) );
pgmoin = (PMQGMO)memcpy(pgmoin, &GetMsgOpts, sizeof(MQGMO) );
memcpy(&pmdin->CorrelId,&pmdin->MsgId,sizeof(&pmdin->CorrelId));
memset(Buffer,'\x0',sizeof(Buffer));
MQGET(Hcon,
Hobj,
pmdin,
pgmoin,
BufferLength,
Buffer,
&DataLength,
&CompCode,
&Reason);
.....
|
Last edited by LuisFer on Tue Jan 08, 2008 11:31 am; edited 1 time in total |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Jan 08, 2008 11:28 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Also, the easiest way to use a separate queue for each client is to use a dynamic queue - either temporary or permanent based on the persistence requirements. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
LuisFer |
Posted: Tue Jan 08, 2008 11:35 am Post subject: |
|
|
 Partisan
Joined: 17 Aug 2002 Posts: 302
|
jefflowrey wrote: |
Also, the easiest way to use a separate queue for each client is to use a dynamic queue - either temporary or permanent based on the persistence requirements. |
But, the performance.... ufff  |
|
Back to top |
|
 |
Danny12345 |
Posted: Tue Jan 08, 2008 11:35 am Post subject: |
|
|
Newbie
Joined: 08 Jan 2008 Posts: 4
|
tleichen wrote: |
I second Peter's comment. DON'T have multiple apps using the same queue, especially if you're new to MQ. It makes a simple problem much more difficult and opens up a real can of worms that you really don't want to get into.  |
I see. How would you set up the System then ? Knowing there's N Clients and but 1 Server, would you set up N queue pairs (1 pair = 2 queues = 1 request + 1 reply) ? And then have the Server application listen to N queues ? Know that the main reason why I - in my first solution - choose to have but 1 pair is to allow to easily (rapidly) add a new Client instance without having to set up a additional queue pair. With this new solution, I will have to inform (reboot ?) the Server to let it know a new Client has joined .. |
|
Back to top |
|
 |
PeterPotkay |
Posted: Tue Jan 08, 2008 11:41 am Post subject: |
|
|
 Poobah
Joined: 15 May 2001 Posts: 7722
|
One REQUEST q for the server app.
A dedicated REPLY queue for each client.
The server app sends the replies to the request message's MQMD_ReplyToQueue.
The requesting app has one instance pushing out request messages, and another instance listening on its dedicated reply queue consuming any and all messages immediatly as they arrive on its reply q.
Unless there are hundreds or thousands of clients, I would prefer to take the time and create actual local reply queues (versus using dynamic queues). More control, you can set up monitoring and alerting better, etc. _________________ Peter Potkay
Keep Calm and MQ On |
|
Back to top |
|
 |
bower5932 |
Posted: Tue Jan 08, 2008 11:43 am Post subject: |
|
|
 Jedi Knight
Joined: 27 Aug 2001 Posts: 3023 Location: Dallas, TX, USA
|
The server only needs to read from its one queue. The clients can put their reply-to-queue in their request message and the server can then put a reply back to the individual client queues. |
|
Back to top |
|
 |
Danny12345 |
Posted: Tue Jan 08, 2008 11:48 am Post subject: |
|
|
Newbie
Joined: 08 Jan 2008 Posts: 4
|
PeterPotkay wrote: |
One REQUEST q for the server app.
A dedicated REPLY queue for each client.
The server app sends the replies to the request message's MQMD_ReplyToQueue.
The requesting app has one instance pushing out request messages, and another instance listening on its dedicated reply queue consuming any and all messages immediatly as they arrive on its reply q.
Unless there are hundreds or thousands of clients, I would prefer to take the time and create actual local reply queues (versus using dynamic queues). More control, you can set up monitoring and alerting better, etc. |
You're absolutely right ! That indeed seems to be the most elegant solution. One could say that the Client is identified by its (unique) reply queue. Thanks to you all for your help. ! |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Jan 08, 2008 12:09 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
The replying app still needs to know how to associate the reply it gets from the queue, with the request that was sent out
If the request was sent out from a different application instance, then you're going to have to do something to share this information between the two application memory spaces.
Unless the reply is entirely unrelated to the request, or contains the full information in the original request. In either of those cases, then, it's not really a "request/reply" scenario. It's an uncorrelated set of two sends. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
|