Author |
Message
|
fjb_saper |
Posted: Sat Sep 22, 2007 4:30 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
My guess is you have a subscription on queue:
CADS6.192.168.2.10_2007.09.21_20.03.10.PS on qmgr QM_CADS6 and the queue no longer exists.
The message reminds you that it is time for some housekeeping and to remove the subscription as the queue has been deleted...
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sat Sep 22, 2007 9:28 am Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
The problem is :
I have no code disconnecting the queue manager or deleting, closing or unsubscribing something related to the queue subscriptions. The 2052 error occurs while application is looping on the response queue for getting messages. The c# API does not handle that 2052 error, unfortunately. What makes me know that there is a problem is : when broker catches the 2052 error, at the same time the application loop gets an empty message from the response queue where it should get at least MQRFH header.
There's may be a relation between that error and the load of the client or multithreading. But how to establish that relation when we know that all messaging stuff is created and stored on queue manager and not on client ? |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Sep 22, 2007 6:34 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
kayoumt wrote: |
The problem is :
I have no code disconnecting the queue manager or deleting, closing or unsubscribing something related to the queue subscriptions. The 2052 error occurs while application is looping on the response queue for getting messages. The c# API does not handle that 2052 error, unfortunately. What makes me know that there is a problem is : when broker catches the 2052 error, at the same time the application loop gets an empty message from the response queue where it should get at least MQRFH header.
There's may be a relation between that error and the load of the client or multithreading. But how to establish that relation when we know that all messaging stuff is created and stored on queue manager and not on client ? |
Use support pack IH03 (RFHUTIL and rfhutilc) to do your housekeeping.
You will need the full MQClient install for rfhutilc.
You may not be able to get messages because the broker is not able to reach one of the destinations as it no longer exits... hence the error message...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Sep 23, 2007 1:31 am Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
I have a better understanding of what is going on. I hope, it will help me have more information on the problem i'm having.
THE PROBLEM
When two fast c# threads (in a same application) are working in a producer/consumer mode (one publishing message on the broker queue, the other one reading replies on a temporary dynamic queue), the broker sends sometimes an empty message on the reply queue (at the same time, it writes error 2052 MQRC_Q_DELETED in the log file).
WORKAROUNDS
1) If I handle the empty message, broker writes 2052 error in log but continues to work and apparently do no longer raises 2052 error until the end of session.
2) If I put message producing (PUT) and consuming (GET) in the same thread, empty message is not sent and broker do not write 2052 error in log.
3) If I open the queue with "WaitInterval = 100" insteaf of "WaitInterval = 0" and MQGMO_WAIT option instead of MQGMO_NO_WAIT, things seem better. |
|
Back to top |
|
 |
jefflowrey |
Posted: Sun Sep 23, 2007 4:29 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Just to confirm a couple of things: you're now no longer getting the FDCs thrown, or any errors shown in the MQ system log other than the 2052? _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Sep 23, 2007 4:33 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
kayoumt wrote: |
I have a better understanding of what is going on. I hope, it will help me have more information on the problem i'm having.
THE PROBLEM
When two fast c# threads (in a same application) are working in a producer/consumer mode (one publishing message on the broker queue, the other one reading replies on a temporary dynamic queue), the broker sends sometimes an empty message on the reply queue (at the same time, it writes error 2052 MQRC_Q_DELETED in the log file).
WORKAROUNDS
1) If I handle the empty message, broker writes 2052 error in log but continues to work and apparently do no longer raises 2052 error until the end of session.
2) If I put message producing (PUT) and consuming (GET) in the same thread, empty message is not sent and broker do not write 2052 error in log.
3) If I open the queue with "WaitInterval = 100" insteaf of "WaitInterval = 0" and MQGMO_WAIT option instead of MQGMO_NO_WAIT, things seem better. |
Have you tried separating completely your put and get operations?
different connections different handles etc...
Typically in a pub/sub model the pub and sub applications are different application to the extend that they even reside on different hosts. So sharing a connection / multithreading both put an get in the same application is quite uncommon and can potentially lead to surprises due to stuff that never entered the original design of the pattern.  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Sep 23, 2007 1:44 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
PUT and GET do not operate on the same queue :
1) PUT writes messages on broker queue (SYSTEM.BROKER.DEFAULT.STREAM).
2) Broker writes messages on application's Temporary Dynamic Reply Queue.
3) GET reads messages from application's Temporary Dynamic Reply Queue.
I think the processing model is very common. What may be I did not do correctly is setting correctly the queue manager for making possible multithreading. See googling result below.
http://www.mqseries.net/phpBB2/viewtopic.php?t=28757&view=previous&sid=f8bdcf0a3645eb42ef0f27c25d9baa48
"
If you specify the MQCNO_HANDLE_SHARE_BLOCK or MQCNO_HANDLE_SHARE_NO_BLOCK option, the handle returned is a shared handle.
The scope of a shared handle is the process that owns the thread from which the call was issued; the handle can be used from any thread that belongs to that process. Not all platforms support threads.
"
http://www.mqseries.net/phpBB2/viewtopic.php?t=28757&view=previous&sid=f8bdcf0a3645eb42ef0f27c25d9baa48
"
By default, when the .NET MQQueueManager object connects to the queue manager it uses MQCNO_HANDLE_SHARE_BLOCK - ie shared between threads but blocking whilst another thread is using the connection - this is the case unless the application is running in a COM+ transaction environment, where the MQCNO_HANDLE_SHARE_NONE option is forced.
" |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Sep 23, 2007 5:28 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
What I am trying to get at is that you're not doing a request / reply pattern but a publish/subscribe pattern.
In a publish/subscribe pattern the connections are best completely separate.
No need for multithreading as you do not want connections to block while they are busy (performance impact)...
Of course depending on what your platform supports you can do multithreading but I would not advise it. Main reason here is scalability.
You publishing application needs to scale in a completely different manner from your subscribing/consuming application...
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Sep 23, 2007 5:57 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
Thanks for advise, fjb_saper. I understand your point.
My C++ (server application) is built exactly according of what you are suggesting. There's only one thread (the main thread) reading the message queue every second and sending back response.
But, a .NET application with GUI (or any GUI-based framework) could not not work that way. Those frameworks are event-driven ; that is, once application is started you do not have the control of the main application thread.
Then, if you want time-to-time to read messages that are not replies, but just subscribes from other applications, you need at least a second thread for checking the published messages while the main thread is taking care of GUI events. In languages like VB6, this kind-of multithreading is achived by "event timers" since those languages are not multi-threaded. But, "event-programming" is little bit "dirty" and very difficult to control. Starting a thread (concurrent to the main thread) which is in charge of only listening for publishes is a safer way to deal with this issue.
So far, what I saw in my application's case is :
When I have :
- Main thread + 1 second thread : my application seems to be fine.
- Main thread + 2 or more second threads, something fails and broker writes 2052 error. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sun Sep 23, 2007 7:00 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
IMHO what you have are really 2 applications:
a) consuming the Publishes => no user interaction (no gui) and event driven.
b) a GUI application that probably does request/response pattern and may or maynot do publishes...
In consequence you should really have 2 executables. For performance and scalability you may need to have multiple instances of a running whereas one instance of b will probably be enough.
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Sun Sep 23, 2007 9:15 pm Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
It is a real time application : a) and b) could not be separated. Recieved publishes notify to the GUI form to update (refresh) the data it is showing to user. This processing model could not be multi-process ; it could only be multi-thread or event-driven. |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Sep 24, 2007 3:11 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20763 Location: LI,NY
|
kayoumt wrote: |
It is a real time application : a) and b) could not be separated. Recieved publishes notify to the GUI form to update (refresh) the data it is showing to user. This processing model could not be multi-process ; it could only be multi-thread or event-driven. |
There is always a way to change that model...
For instance you could create a proxy that updates its values from the publishes and is being polled by the GUI...
This would allow you to scale the consuming app independently as the publishes would be consumed updating the proxy.  _________________ MQ & Broker admin |
|
Back to top |
|
 |
kayoumt |
Posted: Mon Sep 24, 2007 11:39 am Post subject: |
|
|
Voyager
Joined: 18 Sep 2007 Posts: 81
|
Your proxy solution could not work in a REAL TIME model. The GUI has not decide and could not decide what time it has to extract publishes from queues. The GUI could not interrupt user interaction for checking publishes (with or without proxy). A GUI does not have a "main" function like in C or C++ console program. Hence, it has no main execution thread. That proxy that you are suggesting is my thread and that thread could not be outside of the executable that contains the GUI and has to do GUI refreshes without interrupting GUI executions.
I worked on the problem again all night long yesterday. I came to the conclusion that there was more a multithreading issue than MQSeries issue. C# GUI is not thread safe ; then, there is a way to do synchronization of threads with GUI. But, I realized that with more than one concurrent thread I did not have enough understanding of C# multithreading for making it work.
SOLUTION :
I had three threads with the GUI code. I eliminated two threads and kept all my real time stuff in only one thread. So far, it works. See sample code below.
public void ThreadLoop()
{
DateTime var_alive_start_time = DateTime.Now;
DateTime var_watch_start_time = DateTime.Now;
for (;;)
{
// HandleSubscribedEvent
Message publish_msg = SUBSCRIBER.Recieve();
if (publish_msg != null) HandleSubscribedEvent(publish_msg);
// HandleWatchEvent
if (((TimeSpan)(DateTime.Now - var_watch_start_time)).TotalMilliseconds > 100)
{
HandleWatchEvent();
var_watch_start_time = DateTime.Now;
}
// SendIamAlive
if (((TimeSpan)(DateTime.Now - var_alive_start_time)).TotalMilliseconds > 100)
{
SendIamAlive();
var_alive_start_time = DateTime.Now;
}
// DoEvents
Application.DoEvents();
}
} |
|
Back to top |
|
 |
|