|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
MQGET MQPUT Race Condition |
« View previous topic :: View next topic » |
Author |
Message
|
rockdale |
Posted: Mon Dec 14, 2009 11:11 am Post subject: MQGET MQPUT Race Condition |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
This is a long post to descript my questions as I am very new to MQ series/OpenVMS
Our C application is running on OpenVMS, its major task is to transmit messages between a MQ server and another application. We have no control on the MQ server side as it is in outside system. The application does MQGET to read message from MQ and then send this message throught TCP/IP socket to another application. On the other hand, when another application sends data to the application, the application will get an ASP( like interrupt, or event-trigger in windows) to read data from the TCP/IP buffer and then MQPUT this message into the MQ server.
Our application is single thread. to Avoid "2219 MQRC_CALL_IN_PROGRESS" error, we have our own lock for MQGET and MQPUT. mqlock has 3 states: IDLE, GET and PUT. Only when mqlock is IDLE, then it can proceed to MQGET or MQPUT, othewise, the MQGET or MQPUT is skipped.
The flow looks like this:
while(true)
{
if(mqlock==IDLE){
mqlock = GET;
MQGET();
IF(NO_DATA_AVAILABLE)
{
SLEEP(1);
}ELSE{
//DO something with the message
}
}ELSE{
//MISSED A GET
}
}
On TCP/IP AST side, after I read data from TCP/IP buffer
if(mqlock==IDLE)
{
mqlock = PUT;
MQPUT();
mqlock = IDLE;
}else
{
//MISSED A PUT;
}
The application works without any problems for a long time, recently when I was asked to review the design/architecture of it. I find that this might be a bug, when the application need to put message to the MQ, if it can not get the mqlock, the message to be put gets lost. Although in the real world, this never happened. Another thing is our customer does not really like suing polling to do the MQGET().
So here are my questions:
1. Are there any other ways to do MQGET(). For example, Could the application get an interrupt/event when there is a new message be put into the output queue in MQ server?
2. The application is using a classic poll to get message, in a while loop, MQGET(), if no message, sleep 1 second, then retry. The MQGET does not wait(MQGMO_NO_WAIT) for new message since we must allow PUTs when no inbound messages. Is it better to change the MQGET to wait with a timeout 1 second? If change to wait, does it mean within this 1 second, (if no message), the application will not respond to anything even the AST(event)?
3. I read about the option of MQCNO_HANDLE_SHARE_BLOCK when issue MQCONNX, It is for multi-threads, in our case, single thread, can I use MQCNO_HANDLE_SHARE_BLOCK so that I do not our own lock, and the MQPUT will waiting until the MQGET finish? this way, the message to be put will not lost?
4. If answer for question 3 is NO, I am thinking change to multi-threads, main thread handles the MQGET and TCP SEND, and secondary thread handles the MQPUT and TCP RECEIVE. Does MQCONNX thread-safe in OpenVMS or should I use 2 different MQCONNX in 2 threads?
Thanks in advance
-Rockdale
Last edited by rockdale on Mon Dec 14, 2009 11:52 am; edited 2 times in total |
|
Back to top |
|
 |
bruce2359 |
Posted: Mon Dec 14, 2009 11:26 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9470 Location: US: west coast, almost. Otherwise, enroute.
|
If no message currently exists in the queue, MQGET with WAIT will wait n seconds before the wait expires - at which time, the app will recieve a 2033 no-message-available. If a message arrives before the n seconds, the wait will end immediately, and the program will get the msg. _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
Vitor |
Posted: Mon Dec 14, 2009 5:57 pm Post subject: Re: MQGET MQPUT Race Condition |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
rockdale wrote: |
1. Are there any other ways to do MQGET(). For example, Could the application get an interrupt/event when there is a new message be put into the output queue in MQ server? |
Not until you get WMQv7 on OpenVMS, which (on other platforms at least) incorporates this kind of functionality.
rockdale wrote: |
2. The application is using a classic poll to get message, in a while loop, MQGET(), if no message, sleep 1 second, then retry. The MQGET does not wait(MQGMO_NO_WAIT) for new message since we must allow PUTs when no inbound messages. Is it better to change the MQGET to wait with a timeout 1 second? If change to wait, does it mean within this 1 second, (if no message), the application will not respond to anything even the AST(event)? |
Yes, the MQGet will block the thread until the wait expires.
rockdale wrote: |
3. I read about the option of MQCNO_HANDLE_SHARE_BLOCK when issue MQCONNX, It is for multi-threads, in our case, single thread, can I use MQCNO_HANDLE_SHARE_BLOCK so that I do not our own lock, and the MQPUT will waiting until the MQGET finish? this way, the message to be put will not lost? |
I don't believe that connection option can be used for what you want.
rockdale wrote: |
4. If answer for question 3 is NO, I am thinking change to multi-threads, main thread handles the MQGET and TCP SEND, and secondary thread handles the MQPUT and TCP RECEIVE. Does MQCONNX thread-safe in OpenVMS or should I use 2 different MQCONNX in 2 threads? |
AFAIK WMQ connections are not thread safe on any platform and you'll need separate connections. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
rockdale |
Posted: Mon Dec 14, 2009 7:40 pm Post subject: Re: MQGET MQPUT Race Condition |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
Vitor wrote: |
Not until you get WMQv7 on OpenVMS, which (on other platforms at least) incorporates this kind of functionality.
|
The MQ Server version is 7.0.0.0.
The MQ Client version is 6.0.1.1 -which runs on openVMS.
Can you elaborate what behavior exactly WMQv7 supports?
Vitor wrote: |
AFAIK WMQ connections are not thread safe on any platform and you'll need separate connections. |
IF WMQ connections are not thread safe, why they provide the options (MQCNO_HANDLE_SHARE_NONE, MQCNO_HANDLE_SHARE_BLOCK and MQCNO_HANDLE_SHARE_NO_BLOCK) for MQCONNX? quote from MS doc "They control the sharing of handles between different threads (units of parallel processing) within the same process."
So I have to create 2 different MQCONNX in these 2 threads, Quote from MQ doc "Only one call per application connection can be processed at a time.", it won't get the 2219 MQRC_CALL_IN_PROGRESS error since MQGET and MQPUT are using different MQCONNX, right?
Is this the way to go? Or any other better solution?
Thanks again.
-Rockdale |
|
Back to top |
|
 |
Vitor |
Posted: Mon Dec 14, 2009 8:38 pm Post subject: Re: MQGET MQPUT Race Condition |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
rockdale wrote: |
Can you elaborate what behavior exactly WMQv7 supports? |
It supports callbacks as described here
rockdale wrote: |
Vitor wrote: |
AFAIK WMQ connections are not thread safe on any platform and you'll need separate connections. |
IF WMQ connections are not thread safe, why they provide the options (MQCNO_HANDLE_SHARE_NONE, MQCNO_HANDLE_SHARE_BLOCK and MQCNO_HANDLE_SHARE_NO_BLOCK) for MQCONNX? quote from MS doc "They control the sharing of handles between different threads (units of parallel processing) within the same process." |
So I'm wrong. It happens. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Dec 15, 2009 4:50 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
To be clear, an MQGET with wait does more than block the thread it's using.
It also blocks the connection.
So if you have a multi-threaded application and you are sharing the same connection between threads, and one thread sits in MQGET with WAIT, then no other thread can use the connection until the MQGET returns. Even if the connection is usable from the other threads. |
|
Back to top |
|
 |
rockdale |
Posted: Tue Dec 15, 2009 6:05 am Post subject: |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
mqjeff wrote: |
So if you have a multi-threaded application and you are sharing the same connection between threads, and one thread sits in MQGET with WAIT, then no other thread can use the connection until the MQGET returns. Even if the connection is usable from the other threads. |
In this case, is it better just use 2 connections in those 2 threads?
From your experience, what is the best design/implementation for this situation? I believe this is a very common situation, the application need to read from a MQ queue, doing something about the message (write to database, send to somewhere), the application also need to put message into another MQ queue. Or we should just let the application ONLY get the message from MQ, another application ONLY put the message into MQ? So that, it won't have 2219 error at all?
Thanks
-Rockdale |
|
Back to top |
|
 |
rockdale |
Posted: Tue Dec 15, 2009 6:06 am Post subject: Re: MQGET MQPUT Race Condition |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
rockdale wrote: |
Vitor wrote: |
AFAIK WMQ connections are not thread safe on any platform and you'll need separate connections. |
IF WMQ connections are not thread safe, why they provide the options (MQCNO_HANDLE_SHARE_NONE, MQCNO_HANDLE_SHARE_BLOCK and MQCNO_HANDLE_SHARE_NO_BLOCK) for MQCONNX? quote from MS doc "They control the sharing of handles between different threads (units of parallel processing) within the same process." |
So I'm wrong. It happens.[/quote]
I also read something about
The MQ connection is not threadsafe, you need 1 connection per thread. But forgot where I read it from. |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Dec 15, 2009 6:48 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
There's nothing particularly special about your requirements. You don't need the lock. You don't apparently need separate threads or separate connections.
Your application appears to be a "server" type application, that should sit in an MQGET with WAIT call until a message arrives, do it's work including putting messages to other queues, and then go back and wait for another message.
If you need to be processing two messages simultaneously, then you need two connections with two MQGETs, preferably in their own thread.
This is pretty much basic MQ app design, and is illustrated fairly well by the sample code.
You want a WAIT that's long enough to ensure you get a message, but short enough so that your admin isn't twiddling her thumbs while waiting for your app to quiesce when she goes to shut the qmgr down (even so you should still code MQGMO_FAIL_IF_QUIESCE) |
|
Back to top |
|
 |
bruce2359 |
Posted: Tue Dec 15, 2009 6:56 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9470 Location: US: west coast, almost. Otherwise, enroute.
|
Quote: |
You want a WAIT that's long enough to ensure you get a message, but short enough so that your admin isn't twiddling her thumbs while waiting for your app to quiesce when she goes to shut the qmgr down... |
Given that the arrival of a msg immediately cancels the WAIT, if there is no message in the queue, too short a wait interval means that your app will continuously come back to life to detect that there is NO_MSG_AVAILABLE. While not all that painful, it does use up cpu cycles.
I'm more concerned with Jeff's observation about too long a waitinterval. 30 Seconds or one-minute waitinterval seems a good balance. Longer than that makes a sysadmin nervous after an endmqm -c (controlled/graceful quiesce). _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
rockdale |
Posted: Tue Dec 15, 2009 7:51 am Post subject: |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
mqjeff wrote: |
Your application appears to be a "server" type application, that should sit in an MQGET with WAIT call until a message arrives, do it's work including putting messages to other queues, and then go back and wait for another message.
|
While it in an MQGET with WAIT, if no I have data in the TCPIP buffer,(It is on openVMS AST) the process paused and turns to process the AST function(which is reading the data from TCPIP buffer and then PUT it into another queue on MQ Server), here I will get the 2219 error, since I was trying to MQGET (it is not finish yet) and now I can not issue MQPUT from the same connection.
The problem is the AST on openVMS, it is like signal on Unix, When an AST is delivered to the process, it interrupts the mainline processing. and turns to process the AST routine.
Thanks
-Phelix |
|
Back to top |
|
 |
bruce2359 |
Posted: Tue Dec 15, 2009 8:45 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9470 Location: US: west coast, almost. Otherwise, enroute.
|
Quote: |
and now I can not issue MQPUT from the same connection. |
Why not? What symptom? What reasoncode? _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
rockdale |
Posted: Tue Dec 15, 2009 9:01 am Post subject: |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
bruce2359 wrote: |
Quote: |
and now I can not issue MQPUT from the same connection. |
Why not? What symptom? What reasoncode? |
2219 MQRC_CALL_IN_PROGRESS. Since MQGET is active. |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Dec 15, 2009 9:39 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
AH, so the program is reading data from *two* sources, MQ and AST.
Yeah, create two separate connections, one for GETS and one for PUTS.
Then you can reuse the GET connection for any puts that result from the message that's been gotten (because you're not going to go back to the GET state until then), and leave the other connection open for PUTS from AST.
Or are the AST calls the equivalent of API calls to an MQ layer? I mean are you trying to have the app using AST on the other end say "Give me an MQ Message" or "Send an MQ message"? In that case you don't need an MQGet with WAIT loop.
You need a connection pool. |
|
Back to top |
|
 |
rockdale |
Posted: Tue Dec 15, 2009 11:12 am Post subject: |
|
|
Novice
Joined: 03 Dec 2009 Posts: 10
|
The application is single thread.
MQGET get message and then process the message. (here has no problem)
at the same time, the application will respond to AST routine. (stop whatever it doing currently), in the AST routine, the application read from TCP/IP buffer, then MQPUT this message into MQ server.
There are 2 queues in the MQ manager, one for the application get msg from, another for the apploication put msg into.
Basically, the application is loop through MQGET with NO_WAIT, if NO MSG, THEN sleep 1 second, then retry MQGET again, if get a valid msg, process the msg, then retry MQGET again. AT the same time, if tcpip AST triggered, do MQPUT.
since the 2219 error, I use lock around MQGET and MQPUT, also, MQGET with NO_WAIT, What I am trying to do is using MQGET with WAIT and TIMEOUT, at the same time, enable MQPUT anytime.
mqjeff wrote: |
AH, so the program is reading data from *two* sources, MQ and AST.
|
YES.
mqjeff wrote: |
Yeah, create two separate connections, one for GETS and one for PUTS.
Then you can reuse the GET connection for any puts that result from the message that's been gotten (because you're not going to go back to the GET state until then), and leave the other connection open for PUTS from AST.
|
Can I use two MQCONNX in a single thread?
Any overhead about open 2 connections?
If I use MQGET with WAIT,
Vitor wrote: |
Yes, the MQGet will block the thread until the wait expires. |
, does it block AST too?
Again, thanks a lot
-Rockdale |
|
Back to top |
|
 |
|
|
 |
Goto page 1, 2 Next |
Page 1 of 2 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|