error in example "How to wait for multiple messages" ?

Asked by rafal polonski

Hi,

In the example "How to wait for multiple messages" message descriptor: md = pymqi.md() is not withing the loop code so when the script enters the loop he gets the first message and then each subsequent queue.get(None, md, gmo) will raise an exception:

MQMIError: MQI Error. Comp: 2, Reason 2033: FAILED: MQRC_NO_MSG_AVAILABLE

If I understand properly to solve this error, message description code pymqi.md() just has to be withing the loop.

best regards,
rafal

P.S
Dariusz thank you very much for new releases of the pymqi and great updates to the documentation.

Question information

Language:
English Edit question
Status:
Solved
For:
PyMQI Edit question
Assignee:
Dariusz Suchojad Edit question
Solved by:
Dariusz Suchojad
Solved:
Last query:
Last reply:
Revision history for this message
Dariusz Suchojad (dsuch) said :
#1

> md = pymqi.md() is not withing the loop code so when the script enters the loop he gets the first message and then each
> subsequent queue.get(None, md, gmo) will raise an exception:

I can't access my dev environment at the moment and it will take a couple of days until I am able to check it out but I believe you're right, let's keep the question open until I can confirm it, OK?

> thank you very much for new releases of the pymqi and great updates to the documentation.

Sure thing mate! Don't hesitate to let me know if you need anything more be added, I'd be very happy to do it! :-)

Revision history for this message
Best Dariusz Suchojad (dsuch) said :
#2

Hi Rafał,

sorry it took me so long but I'm with you now. The problem was that the very same MQMD object was reused in subsequent calls to queue.get and as you recall, md is being passed by reference which means its .MsgId, .CorrelId and .GroupId attributes are filled in by MQ. So, the first call would use blank IDs but as they would be overwritten by MQ, the second call had no chance to match any message because it was now trying to get the message by MsgId (or Correl- and Group-, depending on what MQ would set there). Just like you said, providing a new md object solved the issue but I guess it's a bit more elegant - and efficient memory-wise - to zero out the IDs after processing the message. In any case, thanks for spotting it! I'll update the examples page soon, here's how the code will look like:

import CMQC
import pymqi

queue_manager = "QM01"
channel = "SVRCONN.1"
host = "192.168.1.135"
port = "1434"
queue_name = "TEST.1"
conn_info = "%s(%s)" % (host, port)

# Message Descriptor
md = pymqi.md()

# Get Message Options
gmo = pymqi.gmo()
gmo.Options = CMQC.MQGMO_WAIT | CMQC.MQGMO_FAIL_IF_QUIESCING
gmo.WaitInterval = 5000 # 5 seconds

qmgr = pymqi.QueueManager(None)
qmgr.connectTCPClient(queue_manager, pymqi.cd(), channel, conn_info)

queue = pymqi.Queue(qmgr, queue_name)

keep_running = True

while keep_running:
    try:
        # Wait up to to gmo.WaitInterval for a new message.
        message = queue.get(None, md, gmo)

        # Process the message here..

        # Reset the MsgId, CorrelId & GroupId so that we
        # can reuse the same 'md' object again.
        md.MsgId = CMQC.MQMI_NONE
        md.CorrelId = CMQC.MQCI_NONE
        md.GroupId = CMQC.MQGI_NONE

    except pymqi.MQMIError, e:
        if e.comp == CMQC.MQCC_FAILED and e.reason == CMQC.MQRC_NO_MSG_AVAILABLE:
            # No messages, that's OK, we can ignore it.
            pass
        else:
            # Some other error condition.
            raise

queue.close()
qmgr.disconnect()

Revision history for this message
rafal polonski (litvos) said :
#3

Thanks Dariusz!

MQMI_NONE is a very nice approach.

Have a good weekend.

rafał