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 » MQCB and MQCTL multi-thread issue

Post new topic  Reply to topic
 MQCB and MQCTL multi-thread issue « View previous topic :: View next topic » 
Author Message
RogerLacroix
PostPosted: Sun Nov 10, 2013 8:53 pm    Post subject: MQCB and MQCTL multi-thread issue Reply with quote

Jedi Knight

Joined: 15 May 2001
Posts: 3252
Location: London, ON Canada

All,

I'm stuck. Help.

I am trying out the MQCB and MQCTL API calls (using WMQ v7.5) to have messages pushed to an async message consumer.

My code dumps out the PID (Process Id) and TID (Thread Id) of the main process and in the async message consumers. I can see that all have the same PID, which is expected and they have different TIDs. The issue I am having is that all message consumers are running under the same TID. i.e. one TID for the main process and one TID for all message consumer.

I have done testing where the MQOPEN, MQCB & MQCTL are against 3 different queues and testing where they are against the same queue. I tried using MQCTLO_THREAD_AFFINITY and without but it made no difference. No matter what I do, I cannot get the message consumers under different TIDs (different from each other).

It is hard to say that the message consumers are running aync when they all use the same TID. I even tried out the MQ sample code called: amqscbf0.c and got the same result. Because all message consumers are using the same TID, the log shows that basically messages are being consumed (from the 3 queues) in a round-robin fashion. But what I want is the 3 message consumers to run in parallel (which can only be done using different TIDs).

I have read and reread the MQ InfoCenter but I cannot figure it out.

What option/parameter do I use to get the combination MQOPEN, MQCB & MQCTL API calls to force the message consumers to be on different TIDs (from each other)?

Regards,
Roger Lacroix
Capitalware Inc.
_________________
Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter
Back to top
View user's profile Send private message Visit poster's website
fjb_saper
PostPosted: Sun Nov 10, 2013 10:40 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

Open a different connection for each async consumer. I believe that your problem is that the messages are synchronized through the connection, hence the round robing... Try opening a different connection for each async consumer and let us know how you fare... AFAIK that's how it's being handled in JMS/XMS
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
PaulClarke
PostPosted: Sun Nov 10, 2013 11:45 pm    Post subject: Reply with quote

Grand Master

Joined: 17 Nov 2005
Posts: 1002
Location: New Zealand

Hi Roger,

I’m not quite sure I understand your question. The main question, I guess, is how many connections do you have ? If you only have one connection then I am surprised that you would expect MQ to call 3 different consumers on 3 different threads at the same time. It would be much more inefficient to keep bouncing between threads. Bear in mind that if you only have one connection then MQ can only deliver one message to one consumer at once. This is obvious if you think what that consumer might do. For example, if you issued MQCMIT() in the consumer you clearly can not risk committing messages in other consumers. So, MQ will ensure that you only have one thing going on at once. Async. consume has many advantages over a traditional MQGET but allowing multiple parallel connections on one HCONN is not one of them

Cheers,
P.
_________________
Paul Clarke
MQGem Software
www.mqgem.com
Back to top
View user's profile Send private message Visit poster's website
RogerLacroix
PostPosted: Mon Nov 11, 2013 9:48 am    Post subject: Reply with quote

Jedi Knight

Joined: 15 May 2001
Posts: 3252
Location: London, ON Canada

fjb_saper wrote:
Open a different connection for each async consumer. I believe that your problem is that the messages are synchronized through the connection, hence the round robing... Try opening a different connection for each async consumer and let us know how you fare... AFAIK that's how it's being handled in JMS/XMS

Yes, I know all of that (me thinks you forget who you are talking to).

Ok. Maybe I should have included the following: 5% (or less) of the work performed by the TID will be related to MQ. Hence, 95% will be backend non-MQ work.

PaulClarke wrote:
I guess, is how many connections do you have ? If you only have one connection then I am surprised that you would expect MQ to call 3 different consumers on 3 different threads at the same time.

One. I never said I wanted 3 MQ API to be performed at the same time, what I said was I wanted each message consumer to be running in its own thread.

PaulClarke wrote:
For example, if you issued MQCMIT() in the consumer you clearly can not risk committing messages in other consumers. So, MQ will ensure that you only have one thing going on at once.

True. And that is why I explicitly set the GMO option to MQGMO_NO_SYNCPOINT which is used on the MQCB call. I am trying to figure how to tell MQ library that I am ok with round-robin at the connection level but I want each message consumer to be started in a separate thread.

PaulClarke wrote:
Async. consume has many advantages over a traditional MQGET but allowing multiple parallel connections on one HCONN is not one of them

That's not what I want. I want each message consumer to be started in a separate thread.

Each message will be less than 1KB that the message consumer will receive. As mentioned, 5% (or less) of the work performed by the thread will be related to MQ and 95% will be backend non-MQ work.

In this case, the bottleneck is not MQ but all of the backend work that the message consumer needs to do. Hence, if each message consumer is started in its own thread, then the application can do more non-MQ work (parallel processing for the backend work).

Does that make more sense?

So, does anyone know of a flag, parameter or environment variable to tell the MQ library to start each message consumer in its own thread?

Regards,
Roger Lacroix
Capitalware Inc.
_________________
Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter
Back to top
View user's profile Send private message Visit poster's website
PaulClarke
PostPosted: Mon Nov 11, 2013 10:08 am    Post subject: Reply with quote

Grand Master

Joined: 17 Nov 2005
Posts: 1002
Location: New Zealand

It does make more sense but I'm not sure you are trying to use MQ incorrectly. Async. consumer is not a scheduler, MQ is not donating threads to the application. The thread is MQ's and should be used for messaging. As it says in the manual....

Quote:
Be aware that if your callback routines use services that could delay or block the thread, for example, MQGET with wait, this could delay the dispatch of other callbacks.


The 'problem' from MQs point of view is that whenever you are in a consumer function you are entitled to issue an MQI call using the given HCONN. Now, in your case you might be sure that your application isn't going to do it but MQ doesn't know this. If in your consumer you did decide to issue MQCMIT() or MQPUT() or any other verb you would expect it to work. You wouldn't expect to be told 'connection busy' because some other consumer is doing something.

I think your two choices are really:

1/ Create a separate connection for each consumer.
Note that in a client you probably have to also say MQCTLO_THREAD_AFFINITY in order to get a thread dedicated to a single connection since the client won't do that by default.

2/ Create a work thread yourself and dispatch the message to it when you get it

Cheers,
Paul.
_________________
Paul Clarke
MQGem Software
www.mqgem.com
Back to top
View user's profile Send private message Visit poster's website
RogerLacroix
PostPosted: Mon Nov 11, 2013 1:53 pm    Post subject: Reply with quote

Jedi Knight

Joined: 15 May 2001
Posts: 3252
Location: London, ON Canada

PaulClarke wrote:
It does make more sense but I'm not sure you are trying to use MQ incorrectly. Async. consumer is not a scheduler, MQ is not donating threads to the application. The thread is MQ's and should be used for messaging. As it says in the manual....

Quote:
Be aware that if your callback routines use services that could delay or block the thread, for example, MQGET with wait, this could delay the dispatch of other callbacks.

True. I was treating it as MQ created a thread for the application to process that particular message.

Usage Note # 5 is what put me on this path thinking that there would be more than 1 thread created:
Quote:
A callback routine should not, in general, rely on being invoked from the same thread each time. If this is required, use the MQCTLO_THREAD_AFFINITY when the connection is started.

So, the MQ library can and/or may create different threads when starting a message consumer. I don't care about connection/message affinity. If every start of a message consumer was in a new (unique) thread that would be fine with me (actually preferred!!!).

PaulClarke wrote:
I think your two choices are really:

1/ Create a separate connection for each consumer.
Note that in a client you probably have to also say MQCTLO_THREAD_AFFINITY in order to get a thread dedicated to a single connection since the client won't do that by default.

2/ Create a work thread yourself and dispatch the message to it when you get it

How exactly would you do number 1 if you did not first create a work thread?

Regards,
Roger Lacroix
Capitalware Inc.
_________________
Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter
Back to top
View user's profile Send private message Visit poster's website
PaulClarke
PostPosted: Mon Nov 11, 2013 2:06 pm    Post subject: Reply with quote

Grand Master

Joined: 17 Nov 2005
Posts: 1002
Location: New Zealand

I'm not sure I understand your question. Just issue as many MQCONNs as you need in the same thread, one after the other. You will, of course, need to make them shared handles....ie. something like MQCNO_HANDLE_SHARE_BLOCK

Cheers,
Paul.
_________________
Paul Clarke
MQGem Software
www.mqgem.com
Back to top
View user's profile Send private message Visit poster's website
RogerLacroix
PostPosted: Mon Nov 11, 2013 4:30 pm    Post subject: Reply with quote

Jedi Knight

Joined: 15 May 2001
Posts: 3252
Location: London, ON Canada

PaulClarke wrote:
Just issue as many MQCONNs as you need in the same thread, one after the other. You will, of course, need to make them shared handles....ie. something like MQCNO_HANDLE_SHARE_BLOCK

How in the world did you get that from the manual?

For MQCNO_HANDLE_SHARE_BLOCK, the manual says
Quote:
Creates a shared connection. On a MQCNO_HANDLE_SHARE_BLOCK connection, if the connection is currently in use by an MQI call on another thread, the MQI call waits until the current MQI call has completed.

Where does it say that option allows you to create multiple connections per thread?

Don't get me wrong - this IS what I was looking for. I added the option and put MQCONNX, MQOPEN, MQCB and MQCTL in a loop and viola, I get the number of threads for the message consumer as the loop counter is set for. Bingo.

Should I be using MQCTLO_THREAD_AFFINITY option with MQCTL? I tried it with and without but it did not seem to make any difference.

Regards,
Roger Lacroix
Capitalware Inc.
_________________
Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter
Back to top
View user's profile Send private message Visit poster's website
PaulClarke
PostPosted: Mon Nov 11, 2013 10:51 pm    Post subject: Reply with quote

Grand Master

Joined: 17 Nov 2005
Posts: 1002
Location: New Zealand

I agree that the manual could be a lot clearer and perhaps this is worthy of a manual update. Shared Handles have been around for many releases, nothing to do with async consume, it would be a shame if most people don't know about them.

As far as using MQCTLO_THREAD_AFFINITY is concerned I think you probably should use it. It's not really what the option is for but if I recall it will have the right affect as a side effect on a client. Be aware that the threading on the server and client is a little different and, of course, may change in the future. However, from what I remember the situation is this:

a) on the server
A thread dedicated to the connection is created as soon as MQCTL is issued and the thread will run for the life of async consume. So, MQCTLO_THREAD_AFFINITY will have no effect since it is doing it anyway.

b) on the client
By default the connection is only associated with a thread when there are messages to be delivered and more than one connection can be associated with the same thread at any one time. This reduces the thread usage. For example it is possible to have 100 connections to the queue manager all with started consumers and yet there be 0 threads in the background to deliver the messages. However, if I recall correctly then specifying MQCTLO_THREAD_AFFINITY will cause the client to dedicate a thread to the connection just like the server. So, in the case of the client I think you should indeed use MQCTLO_THREAD_AFFINITY.


Of course the bottom line is to try it and see what effect you see. If you do find it works then I think it might also be worth getting a manual update no this behaviour since if you are relying on it you don't want MQ to change the dispatching model underneath you. This isn't really what MQCTLO_THREAD_AFFINITY was about after all but it is an understandable by-product.

Cheers,
Paul.
_________________
Paul Clarke
MQGem Software
www.mqgem.com
Back to top
View user's profile Send private message Visit poster's website
mvic
PostPosted: Wed Nov 13, 2013 5:29 pm    Post subject: Reply with quote

Jedi

Joined: 09 Mar 2004
Posts: 2080

RogerLacroix wrote:
PaulClarke wrote:
Just issue as many MQCONNs as you need in the same thread, one after the other. You will, of course, need to make them shared handles....ie. something like MQCNO_HANDLE_SHARE_BLOCK

How in the world did you get that from the manual?

Search the mq info center for the words
Quote:
shared hconn

I am sure the IBM feedback link can be used to tell them how to make this information more accessible or more obvious.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » IBM MQ API Support » MQCB and MQCTL multi-thread issue
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.