5 Replies Latest reply: Dec 14, 2010 2:08 AM by ak RSS

    OpenMQ 4.4 C Client MQUnsubscribeDurableMessageConsumer() Error

      I am using the OpenMQ 4.4 C Client API and the Boost C++ threading library to develop an application. Everything compiles and functions alright, even using durability, EXCEPT when using a large number (100) of threads, all subscribing, publishing messages, and unsubscribing simultaneously. In a race condition, when in my unsubscribe() function, I call MQCloseMessageConsumer() and then MQUnsubscribeDurableMessageConsumer() back-to-back and in very rare cases, MQUnsubscribeDurableMessageConsumer() has an error: MQ_CANNOT_UNSUBSCRIBE_ACTIVE_CONSUMER: Cannot unsubscribe an active consumer.

      I assumed MQUnsubscribeDurableMessageConsumer() is getting called to quickly, so I throw an exception when this occurs and then have the thread sleep for 10 seconds (more than enough time), then attempt to unsubscribe again using MQUnsubscribeDurableMessageConsumer(). This comes back with the exact same error. Why is this failing and what is your suggestion to try to handle it?

      Every thread who attempts to unsubscribe() after this fails on MQCloseMessageConsumer() saying the consumer handle is now invalid (since threads share memory space). Why would the handle now be invalid? Is the call to MQUnsubscribeDurableMessageConsumer() somehow corrupting the handle? If this race condition doesn't occur (if there are fewer threads) then all of the unsubscribing and closing works just fine.

      Please let me know if you can help me. This is detrimental to the code and seems to be unfixable.

      The only way in my mind to get this not to fail and not corrupt the handles so they can be closed properly is to A) not call MQUnsubscribeDurableMessageConsumer() which produces adverse side effects or B) put a sleep between MQCloseMessageConsumer() and MQUnsubscribeDurableMessageConsumer() for each thread, which is terribly inefficient. Neither of these are an option for me, so let me know what can be done.

        • 1. Re: OpenMQ 4.4 C Client MQUnsubscribeDurableMessageConsumer() Error
          The consumerHandle will be invalid after MQCloseMessageConsumer(consumerHandle) function successful return. This is documented in the C-API Developer's Guide

          MQ_CANNOT_UNSUBSCRIBE_ACTIVE_CONSUMER error on MQUnsubscribeDurableMessageConsumer() is an error from broker. What is the broker version ? What does the broker log show when this occurs ? If after the sleep time, unsubscribe the durable consumer still fails with the same error, please first make sure the consumerHandle passed to MQCloseMessageConsumer() is the durable consumer that is created with the same durableName passed to MQUnsubscribeDurableMessageConsumer(), and the consumerHandle was created on a connection with the same clientID as the clientID of the connection for the sessionHandle passed to MQUnsubscribeDurableMessageConsumer().
          • 2. Re: OpenMQ 4.4 C Client MQUnsubscribeDurableMessageConsumer() Error
            I am running Glassfish Enterprise Server 2.1.1 successfully running a broker cluster of OpenMQ 4.4 brokers. Which log are you referring to? I looked in server logs, and the broker log at {Glassfish}/domains/domain1/imq/instances/imqbroker/log/log.txt doesn't have any new information when I run my programs.

            I checked all of these things: durable consumer, same durable name, same clientId, etc. They are all correct. Keep in mind this only happens sometimes, in over 100 threads. Normally everything functions just fine. This is some sore of race condition that happens.

            Any mroe ideas? There is no reason why after a significant sleep, unsubscribing again shouldn't work. It definitely shouldn't come back with the same error again.
            • 3. Re: OpenMQ 4.4 C Client MQUnsubscribeDurableMessageConsumer() Error
              There must be a broker side log message/exception corresponding to the MQ_CANNOT_UNSUBSCRIBE_ACTIVE_CONSUMER error. Please look to all the broker logs in the cluster or if you know the particular broker that the connection for MQUnsubscribeDurableMessageConsumer() call was connected to. Is your application using seperate thread calling MQCloseConsumer() and MQUnsubscribeDurableMessageConsumer() for a durable consumer and has a chance of calling them concurently ? Please note that a session is a single-threded context so multiple threads should not use the same session concurrently nor use the objects it creates concurrently.
              Is the durable consumer on a wildcard Topic ? Were MQCloseConsumer() and MQUnsubscribeDurableMessageConsumer() calls made on different connections potentially to different broker in the cluster ? Does your application create/close/unsubscribe durable consumers frequently ? What the ~100 application threads concurrently doing ?
              • 4. Re: OpenMQ 4.4 C Client MQUnsubscribeDurableMessageConsumer() Error
                So, I realize that we were using one session for all threads because we didn't realize you were not supposed to. In our new restructured code, we share one connection and have multiple threads each creating a session, topic, subscribing to the topic, and listening.

                We then have a separate producer send messages to the topic.

                We have a new problem now, and it may be related to the sessions once again. Say we have 5 threads listening on one topic (each creating a session and a unique consumer). When the producer sends a message, each consumer should receive the message and print to the screen without error. However, we we have instead is the 1st consumer receives and prints it just fine, with no errors. For the next 4 consumers, each one will successfully receive and print the message, but will also have an error in the call to MQAcknowledgeMessages(sessionHandle, messageHandle); :

                MQ_MESSAGE_NOT_IN_SESSION: Message was not delivered to session

                This always happens in this order, where the 1st consumer receives it fine and no error and the next 5 print this.

                1) We don't understand this error. In reading the documentation, it says nothing about what might be causing the error, only that it is common. What could be causing this type of error?

                2) Do you see anything specifically wrong with our methodology and reasoning that would make this not work and return errors?

                • 5. Re: OpenMQ 4.4 C Client MQUnsubscribeDurableMessageConsumer() Error
                  It appears that your application was calling MQAcknowledgeMessages(sessionHandle, messageHandle) with a sessionhandle that is not the Session that the message, represented by the messageHandle, was received on. The sessionHandle need to be the handle to the session for the consumer that received the message. Please see MQ C-API Reference