Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python running MessageQueue.Peek via win32com, how to get timeout right?

For starters, I would like to say if anyone can help here, you are incredible.

General Question

My Python program needs to interact with MSMQ. Basically, I want to peek at a queue, specifying a timeout if there's nothing in the queue.

However, despite my best efforts, I cannot get Peek() to wait out the timeout interval, when there's no value previously in the queue. Can you please point out what is missing from this code?


My Current Code

Here is my code right now:

from socket import gethostname

import win32com.client
import pythoncom

import clr
clr.AddReference("System")
clr.AddReference("System.Messaging")
from System import TimeSpan
from System.Messaging import MessageQueue


# Source: [1]
# [1] https://learn.microsoft.com/en-us/previous-versions/windows/desktop/msmq/ms707027%28v%3dvs.85%29
MQ_DENY_NONE = 0x0
MQ_PEEK_ACCESS = 0x1
MQ_SEND_ACCESS = 0x2


# Set up queue
pythoncom.CoInitialize()
qinfo = win32com.client.Dispatch("MSMQ.MSMQQueueInfo")
qinfo.FormatName = f"direct=os:{gethostname()}\\PRIVATE$\\MyQueue"
queue = qinfo.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)

# Receive a value
timeout_sec = 1.0
timespan = TimeSpan.FromSeconds(timeout_sec)
label, body = "", ""
# TODO: timeout value does not appear working. It never waits when
#  there's no message
if queue.Peek(pythoncom.Empty, pythoncom.Empty, timespan):
    msg = queue.Receive() . # Blocking receive --> remove msg from the queue
    if msg is not None:
        label = msg.Label
        body = msg.Body

I run: inspect.getfullargspec(queue.Peek) and get:

FullArgSpec(args=['self', 'WantDestinationQueue', 'WantBody', 'ReceiveTimeout', 'WantConnectorType'], varargs=None, varkw=None, defaults=(<PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>), kwonlyargs=[], kwonlydefaults=None, annotations={})

Things I've Tried

This question: saying ReceiveTimeout=timespan doesn't seem to solve my problem.

Replacing pythoncom.Empty with pythoncom.Missing doesn't seem to work

This unanswered question seems very similar to mine

like image 287
Intrastellar Explorer Avatar asked May 03 '26 09:05

Intrastellar Explorer


1 Answers

In the original question's comments, @PeterBrittain suggested to try just using:

an integer (in milliseconds) for their timeout

I got around to trying that out, and actually, it worked! I found float values to work as well. Here is some sample Python code:

timeout_sec = 1.0
queue.Peek(pythoncom.Empty, pythoncom.Empty, timeout_sec * 1000):

Thank you @PeterBrittain!

like image 183
Intrastellar Explorer Avatar answered May 05 '26 22:05

Intrastellar Explorer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!