Author |
Message
|
kumoyuki |
Posted: Mon Jul 26, 2010 2:43 am Post subject: Multiple Connections |
|
|
Newbie
Joined: 26 Jul 2010 Posts: 8
|
Hi all -
I imagine that this is something that ought to be a FAQ, but i'm not finding it as I trawl through the net. In short, I have an application (on u$oft Windows) that has multiple independent subsystems which are communicating via MQ. Each of these subsystems currently performs their own MQCONNX and MQDISC calls, but they are all receiving the same connection handle from the MQ API. This is leading to problems where connections are not open in various places they are expected to be.
I've been poking at various options to MQCONNX, but nothing seems to change this behavior. Is it just impossible to establish multiple queue manager connections from within a single windows exe?
TIA |
|
Back to top |
|
 |
Vitor |
Posted: Mon Jul 26, 2010 4:13 am Post subject: Re: Multiple Connections |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
kumoyuki wrote: |
Is it just impossible to establish multiple queue manager connections from within a single windows exe? |
Yes. Unless the exe is multi-threaded in which case each thread can have it's own connection but must have it's own connection. They can't be shared between threads.
I'm interested in your design here. If the subsystems are so independant they do their own connections (and apparently interconnect via WMQ) why have them in a single exe? Breaking them out would solve your problem and, if they're already making independant connections, have no effect on their working?
What's the requirement here to have them lumped as one? _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Jul 26, 2010 4:25 am Post subject: Re: Multiple Connections |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
|
Back to top |
|
 |
Vitor |
Posted: Mon Jul 26, 2010 4:36 am Post subject: Re: Multiple Connections |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
Well I'll be!  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Jul 26, 2010 4:39 am Post subject: Re: Multiple Connections |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
|
Back to top |
|
 |
kumoyuki |
Posted: Mon Jul 26, 2010 6:03 am Post subject: Re: Multiple Connections |
|
|
Newbie
Joined: 26 Jul 2010 Posts: 8
|
Vitor wrote: |
kumoyuki wrote: |
Is it just impossible to establish multiple queue manager connections from within a single windows exe? |
If the subsystems are so independant they do their own connections (and apparently interconnect via WMQ) why have them in a single exe? ... What's the requirement here to have them lumped as one? |
Legacy (ca. 1996) software architecture built using a Big Ball of Mud pattern (see http://www.laputan.org/mud). I've spent the last two years decomposing it to the point where we're actually going to have real network interfaces, but conformance to the Keeping It Working pattern on a 12-week release cycle makes it hard to split up the tar-baby.
Having to manage the MQHCONN globally is that extra bit of pain, but its hardly noticeable compared to the rest of the system... |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Jul 26, 2010 6:21 am Post subject: Re: Multiple Connections |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
kumoyuki wrote: |
Having to manage the MQHCONN globally is that extra bit of pain, but its hardly noticeable compared to the rest of the system... |
it's not clear that you need to do so, and it's not clear why particularly you're having issues.
As has been noted, you can share connections between threads - but if you're issuing MQCONNX in multiple threads, then without specifying the sharing options explicitly, you should be getting a new connection each time.
Can you verify your internal results that suggest you're re-using the same conn with the output of DISPLAY CONNECTION on the queue manager at the same time?
Can you confirm that you're using MQ v6 or MQ v7? |
|
Back to top |
|
 |
kumoyuki |
Posted: Mon Jul 26, 2010 6:40 am Post subject: Re: Multiple Connections |
|
|
Newbie
Joined: 26 Jul 2010 Posts: 8
|
>> Having to manage the MQHCONN globally is that extra bit of pain, but
>> its hardly noticeable compared to the rest of the system...
> it's not clear that you need to do so
Well based on the documentation, I thought that i could manage MQHCONNs within individual modules; however, every call that is being made within the application to MQCONNX is returning to me identical MQHCONN values (specifically MQHCONN == 6).
> and it's not clear why particularly you're having issues.
That's why I've posted!
> As has been noted, you can share connections between threads
The application is single-threaded, and will always be. I spent four months trying to liberate the code from its single-threaded architecture and failed.
> but if you're issuing MQCONNX in multiple threads,
I am not.
> then without specifying the sharing options explicitly
I have tried various sharing options settings, on the off chance that I might get a different handle. WMQ appears to *really like* the number 6.
> you should be getting a new connection each time.
Not.
> Can you verify your internal results that suggest you're re-using the
> same conn with the output of DISPLAY CONNECTION on the queue
> manager at the same time?
I will look into this (tomorrow - its Miller time locally), but given the remaining symptoms; namely that all the MQHCONNs received through the API are the same and that closing any of them appears to close them all (inferred from subsequent error messages as different modules go through their shutdown process), I think the evidence is pretty conclusive.
> Can you confirm that you're using MQ v6 or MQ v7?
The latest version I installed was v7, but it is relatively new to us |
|
Back to top |
|
 |
mqjeff |
Posted: Mon Jul 26, 2010 6:58 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
I'm not sure what MQHCONN==6 means.
An MQHCONN is a pointer, and as such it's value isn't really something to be treated as meaningful.
Are you using a BINDINGS connection? That is, are you issuing MQCONNX to a queue manager on the same machine without using any client information? There are some comments in the APG about not being able to create more than one BINDINGS connection to the same qmgr from the same thread (and not being able to create a bindings connection to more than one queue manager from the same application).
Even if you can't get the rest of the application to run in multiple threads, you might be able to run multiple threads that just do MQ stuff. i.e. replace everywhere the app calls MQPUT with something that invokes a routine on another thread that does the actual PUT.
Be aware that if at any point in a single-threaded application, you are doing an MQGET-with-WAIT, then everything waits. I'm sure you've felt this pain, but it's worth a reminder. |
|
Back to top |
|
 |
kumoyuki |
Posted: Mon Jul 26, 2010 10:11 pm Post subject: |
|
|
Newbie
Joined: 26 Jul 2010 Posts: 8
|
> I'm not sure what MQHCONN==6 means.
It means that every call to MQCONN or MQCONNX returns to me a handle of type MHQCONN where the value is equal to 6.
> An MQHCONN is a pointer, and as such it's value isn't really
> something to be treated as meaningful.
Nevertheless the fact of its persistent, identical value would tend to indicate that it is referencing something that is the same, don't you think? I never ascribed any meaning to the value other than to note that it was always the same.
> Are you using a BINDINGS connection? That is, are you issuing
> MQCONNX to a queue manager on the same machine without using
> any client information?
My dev test configuration does indeed have the queue manager running on the local machine. I wouldn't know a BINDINGS connection if it bit me on the nose, but here is the latest iteration of the MQCONNX code:
MQHCONN handle = -1;
MQLONG CC = MQCC_OK;
MQLONG Reason = MQRC_NONE;
MQCD client = {MQCD_CLIENT_CONN_DEFAULT};
strncpy(client.ConnectionName, connection_name, MQ_CONN_NAME_LENGTH);
strncpy(client.ChannelName, channel_name, MQ_CHANNEL_NAME_LENGTH);
client.TransportType = transport_type;
MQCNO options = {MQCNO_DEFAULT};
options.Version = MQCNO_VERSION_5;
options.ClientConnPtr = &client;
options.Options |= MQCNO_SERIALIZE_CONN_TAG_Q_MGR;
options.Options |= MQCNO_HANDLE_SHARE_NONE;
memcpy(options.ConnTag, SessionId, 128);
MQCONNX(queue_manager, &options, &handle, &CC, &Reason);
> There are some comments in the APG about not being able to create more than one ...
Interesting. I will poke around looking for that.
> Be aware that if at any point in a single-threaded application, you are doing an
> MQGET-with-WAIT, then everything waits.
I don't wait :) |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Jul 27, 2010 2:22 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Okay, so at no point do you specify the qmgr name, and you specify the conname, transport and channel.
This means that you are establishing a CLIENT connection and not a BINDINGS connection. A bindings connection would just use the qmgr name and would establish an "in-memory" binding to the qmgr.
This means that the comments I mentioned earlier about reusing the same connection don't apply - they only apply to bindings connections.
It also gives some additional ways to confirm that you are or aren't getting multiple connections. When your app has connected, what does DIS CONN show you in runmqsc? What does DIS CHSTATUS(your channel) show you?
Also, have you confirmed that you are always getting CC 0 and Reason 0 after each and every call to MQCONNX? It's MQ programming 101 to double check these, and I have no reason to think that you haven't. But it's always worth the time to dot the i's and cross the t's. |
|
Back to top |
|
 |
kumoyuki |
Posted: Tue Jul 27, 2010 3:12 am Post subject: |
|
|
Newbie
Joined: 26 Jul 2010 Posts: 8
|
> Okay, so at no point do you specify the qmgr name
Actually if you look at the code there is a variable passed as the first param of the MQCONNX call. That cariable holds a string which has the queue manager name in it (that's why it is called queue_manager).
> and you specify the conname, transport and channel.
I have also done those things.
> This means that you are establishing a CLIENT connection and not a
> BINDINGS connection.
That was the impression i was getting from reading the available documents on the web, but everything about BINDINGS is also about Java.
> When your app has connected, what does DIS CONN show you in
> runmqsc? What does DIS CHSTATUS(your channel) show you?
I will check.
> Also, have you confirmed that you are always getting CC 0 and
> Reason 0 after each and every call to MQCONNX?
Yep, but I will make sure that the code is not doing something which is subsequently ignored. |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Jul 27, 2010 4:58 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
kumoyuki wrote: |
> This means that you are establishing a CLIENT connection and not a
> BINDINGS connection.
That was the impression i was getting from reading the available documents on the web, but everything about BINDINGS is also about Java. |
Right. That's the thing I'd forgotten.
Are you linking against mqm.lib or mqic.lib?
You *need* to be linking against mqic.lib for this to work. Otherwise you *will* be establishing a bindings connection. |
|
Back to top |
|
 |
kumoyuki |
Posted: Tue Jul 27, 2010 5:31 am Post subject: |
|
|
Newbie
Joined: 26 Jul 2010 Posts: 8
|
> Are you linking against mqm.lib or mqic.lib?
Dynamically loading mqic32.dll. Literally:
LoadLibrary("mqic32.dll");
> You *need* to be linking against mqic.lib for this to work. Otherwise
> you *will* be establishing a bindings connection.
Hmmm....curioser and curioser |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Jul 27, 2010 6:08 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
mqic32.dll is equivalent to mqic.dll, but the later form is more current.
The LoadLibrary *should* be sufficient. Again, if you are seeing any channel statuses for your svrconn or if the DIS CONN(*) ALL shows your CHANNEL in at least one object, then you know you are using a client connection. |
|
Back to top |
|
 |
|