ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ API Support » MQGET MQPUT Race Condition

Post new topic  Reply to topic Goto page 1, 2  Next
 MQGET MQPUT Race Condition « View previous topic :: View next topic » 
Author Message
rockdale
PostPosted: Mon Dec 14, 2009 11:11 am    Post subject: MQGET MQPUT Race Condition Reply with quote

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
View user's profile Send private message
bruce2359
PostPosted: Mon Dec 14, 2009 11:26 am    Post subject: Reply with quote

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
View user's profile Send private message
Vitor
PostPosted: Mon Dec 14, 2009 5:57 pm    Post subject: Re: MQGET MQPUT Race Condition Reply with quote

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
View user's profile Send private message
rockdale
PostPosted: Mon Dec 14, 2009 7:40 pm    Post subject: Re: MQGET MQPUT Race Condition Reply with quote

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
View user's profile Send private message
Vitor
PostPosted: Mon Dec 14, 2009 8:38 pm    Post subject: Re: MQGET MQPUT Race Condition Reply with quote

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
View user's profile Send private message
mqjeff
PostPosted: Tue Dec 15, 2009 4:50 am    Post subject: Reply with quote

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
View user's profile Send private message
rockdale
PostPosted: Tue Dec 15, 2009 6:05 am    Post subject: Reply with quote

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
View user's profile Send private message
rockdale
PostPosted: Tue Dec 15, 2009 6:06 am    Post subject: Re: MQGET MQPUT Race Condition Reply with quote

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
View user's profile Send private message
mqjeff
PostPosted: Tue Dec 15, 2009 6:48 am    Post subject: Reply with quote

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
View user's profile Send private message
bruce2359
PostPosted: Tue Dec 15, 2009 6:56 am    Post subject: Reply with quote

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
View user's profile Send private message
rockdale
PostPosted: Tue Dec 15, 2009 7:51 am    Post subject: Reply with quote

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
View user's profile Send private message
bruce2359
PostPosted: Tue Dec 15, 2009 8:45 am    Post subject: Reply with quote

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
View user's profile Send private message
rockdale
PostPosted: Tue Dec 15, 2009 9:01 am    Post subject: Reply with quote

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
View user's profile Send private message
mqjeff
PostPosted: Tue Dec 15, 2009 9:39 am    Post subject: Reply with quote

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
View user's profile Send private message
rockdale
PostPosted: Tue Dec 15, 2009 11:12 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ API Support » MQGET MQPUT Race Condition
Jump to:  



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
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.