Author |
Message
|
andy840920 |
Posted: Wed Nov 07, 2007 6:17 am Post subject: when MQGET block, how to MQCLOSE and MQDISC?failed with 2219 |
|
|
Apprentice
Joined: 29 Apr 2007 Posts: 44
|
Code: |
static void SigUsr(int signo)
{
if (signo == SIGUSR1 || signo == SIGUSR2)
ExitResourceFree();
}
static void ExitResourceFree()
{
MQCLOSE();
MQDISC();
exit(0);
}
signal(SIGUSR1, SigUsr);
while (1)
{
MQGET();
/*
mqgmo.Options = MQGMO_WAIT |
MQGMO_CONVERT |
MQGMO_ALL_MSGS_AVAILABLE |
MQGMO_ALL_SEGMENTS_AVAILABLE;
mqgmo.MatchOptions = MQMO_MATCH_CORREL_ID;
mqgmo.WaitInterval = MQWI_UNLIMITED;
*/
//do something
}
|
when i stop my application use kill USR1 pid. but MQCLOSE and MQDISC ended with 2219, how to free the connection?[/code] |
|
Back to top |
|
 |
jefflowrey |
Posted: Wed Nov 07, 2007 6:24 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You can't cancel an MQGET that's in a WAIT state. It will only return from that call (and free the handle) when either a) a message appears on the queue that is eligible to be gotten by the GET, or b) the wait time expires.
That's what the 2219 is telling you - that you're trying to issue MQCLOSE on a connection handle that's in use by your MQGET.
You can code your application to end when it GETs a message with a MQMD.Feedback value of MQFB_QUIT, and then terminate your program that way rather than using SIGUSR1.
Or you can code a shorter wait time... or code your SigUsr to retry the MQCLOSE in a sleep() loop until it doesn't return a bad RC. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
Vitor |
Posted: Wed Nov 07, 2007 6:27 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
Short answer - you can't. The MQGET call is off with the queue manager waiting for a message, so there's no way to send a signal to the queue manager to end the call.
If you're going to use wait unlimited, you need to design a way to send a "stop" message to the queue manager which will end the call and can also trigger application closedown. Another solution is set a wait interval to end the call so the application can loop round, check to see if it's been requested to close, then restart the wait.
You should also include FAIL_IF_QUIESCING on the MQ calls, especially if you're using wait unlimited. If the MQ admin tries to do a controlled close of the queue manager, it'll wait until your programme disconnects. Which on an unlimited wait will never happen. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
Nigelg |
Posted: Wed Nov 07, 2007 7:04 am Post subject: |
|
|
Grand Master
Joined: 02 Aug 2004 Posts: 1046
|
Set the queue that the MQGET is reading from GET(INHIBITED), then the MQGET will return and the app can close. _________________ MQSeries.net helps those who help themselves.. |
|
Back to top |
|
 |
andy840920 |
Posted: Fri Nov 09, 2007 7:02 am Post subject: |
|
|
Apprentice
Joined: 29 Apr 2007 Posts: 44
|
jefflowrey wrote: |
You can't cancel an MQGET that's in a WAIT state. It will only return from that call (and free the handle) when either a) a message appears on the queue that is eligible to be gotten by the GET, or b) the wait time expires.
That's what the 2219 is telling you - that you're trying to issue MQCLOSE on a connection handle that's in use by your MQGET.
You can code your application to end when it GETs a message with a MQMD.Feedback value of MQFB_QUIT, and then terminate your program that way rather than using SIGUSR1.
Or you can code a shorter wait time... or code your SigUsr to retry the MQCLOSE in a sleep() loop until it doesn't return a bad RC. |
but i want stop my application and has not get a message all along. when i do MQCLOSE and MQDISC failed, then "dis queue(MYQUEUE)" command show the IPPROCS has one count. and i must put a message to the queue then IPPROCS count into zero. so if i stop my application failed, the second start my application and the first message can't get always.
so i want stop my application when MQGET operator in a unlimited wait. and my application stoped then the IPPROCS into zero. how to code my application to end when it GETs a message with a MQMD.Feedback value of MQFB_QUIT? i don't understand it. thanks... |
|
Back to top |
|
 |
Vitor |
Posted: Fri Nov 09, 2007 7:08 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
jefflowrey is recommending (I believe) that you break the wait with a message of a specific type, defined in the MQMD.
Bottom line - if you code an unlimited wait, you need to code a way to break it. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
andy840920 |
Posted: Fri Nov 09, 2007 7:14 am Post subject: |
|
|
Apprentice
Joined: 29 Apr 2007 Posts: 44
|
Vitor wrote: |
Short answer - you can't. The MQGET call is off with the queue manager waiting for a message, so there's no way to send a signal to the queue manager to end the call.
If you're going to use wait unlimited, you need to design a way to send a "stop" message to the queue manager which will end the call and can also trigger application closedown. Another solution is set a wait interval to end the call so the application can loop round, check to see if it's been requested to close, then restart the wait.
You should also include FAIL_IF_QUIESCING on the MQ calls, especially if you're using wait unlimited. If the MQ admin tries to do a controlled close of the queue manager, it'll wait until your programme disconnects. Which on an unlimited wait will never happen. |
send a "stop" message and MQGET this message then decide to end the application. but is not the MQ based solution, it's the application level solution.
another solution, even though using wait interval, but my application is a daemon. so MQGET must in a while loop. |
|
Back to top |
|
 |
andy840920 |
Posted: Fri Nov 09, 2007 7:18 am Post subject: |
|
|
Apprentice
Joined: 29 Apr 2007 Posts: 44
|
Nigelg wrote: |
Set the queue that the MQGET is reading from GET(INHIBITED), then the MQGET will return and the app can close. |
how to set the queue that the MQGET is reading from GET(INHIBITED)?
i can't find GET(INHIBITED) info in manual. |
|
Back to top |
|
 |
Vitor |
Posted: Fri Nov 09, 2007 7:21 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
andy840920 wrote: |
send a "stop" message and MQGET this message then decide to end the application. but is not the MQ based solution, it's the application level solution. |
Why is this a problem?
andy840920 wrote: |
another solution, even though using wait interval, but my application is a daemon. so MQGET must in a while loop. |
Again, what's the problem? _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
Vitor |
Posted: Fri Nov 09, 2007 7:22 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
andy840920 wrote: |
i can't find GET(INHIBITED) info in manual. |
It's in the Commands manual, an option of the ALTER QUEUE command. The disadvantage of this method is you need administrative rights to issue it, and must remember to reverse it before you try and restart your application..... _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
jefflowrey |
Posted: Fri Nov 09, 2007 7:26 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
To recap:
The only ways there are to end an MQGET that's inside a WAIT are
1) put a message to the queue that will cause the GET to return
2) Get-disable the queue.
3) The WAIT interval expires
4) terminate your process - this may leave the connection open on the qmgr side.
While the GET is in WAIT, you can't do anything else with the connection handle. You can't close it, or disconnect it, or anything else at all. No matter where in your code you are.
You are currently coding for an UNLIMITED wait interval. So it will never expire.
Altering the queue to get-disable it will be a manual step, and require a manual step to re-enable. You can program these steps if you want. But no matter how you get-disable the queue, your program will receive a non-zero Completion Code and Reason Code from the MQGET. You will have to code special handling for this particular situation.
You can add code to your SIGUSR1 handler to put a message, to cause the MQGet to terminate. But this will require an additional MQ connection.
The simplest solution is to set your WAIT interval to a much smaller number, like 1 minute. Then put a loop over your MQGET, that ends when a specific variable is set. Then in your SIGUSR1 handler, just set the variable. No more than a full minute later, your program will exit the loop, and you can close and disconnect. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
RogerLacroix |
Posted: Fri Nov 09, 2007 9:38 am Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hi Andy,
You have 3 choices:
- Don't use wait unlimited
- Or use the alter command to get inhibit the queue.
- Use the MQMD Feedback code of QUIT.
The first 2 are fine but if you are going to change the application then read the last post (by me) here:
http://www.mqseries.net/phpBB2/viewtopic.php?t=33075
I feel this is the most elegant solution. Hence, you use a simple program, called PutQuitMessage, to put a message on a queue with a MQMD.Feedback with 'QUIT' (and a blank body).
Therefore, the long running receiver application can use 'wait unlimited' and but yet it can be stopped at a moments notice.
Regards,
Roger Lacroix
Capitalware Inc. _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
andy840920 |
Posted: Mon Nov 12, 2007 7:42 am Post subject: |
|
|
Apprentice
Joined: 29 Apr 2007 Posts: 44
|
i'm so sorry to ask how to alter queue to inhibited? i find alter qmgr inhibitved enabled only.so...no alter queue.
and "Use the MQMD Feedback code of QUIT", can you show some sample code? i don't know how to code of MQMD feedback for my question.
the last why MQGET get a empty message (the zero length ) sometimes in my application ?
thanks all. |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Nov 12, 2007 8:01 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
alter qlocal get(disabled)
MQMD.Feedback = MQFB_QUIT _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
Vitor |
Posted: Mon Nov 12, 2007 8:03 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
andy840920 wrote: |
i'm so sorry to ask how to alter queue to inhibited? i find alter qmgr inhibitved enabled only.so...no alter queue. |
What?? You're saying the ALTER QUEUE command only supports GET(ENABLED)?? Not in the doc I'm looking at!
andy840920 wrote: |
"Use the MQMD Feedback code of QUIT", can you show some sample code? i don't know how to code of MQMD feedback for my question. |
It's a constant value supplied in the MQ header file. Assign it to the feedback field in the MQMD
andy840920 wrote: |
the last why MQGET get a empty message (the zero length ) sometimes in my application ? |
Because a zero length messge was put? Or there's a bug in your app?
Other explainations are possible. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
|