I am using the PeekBatch(<messageCount>)
method on the QueueClient
(Windows Azure Service Bus package version 2.1.2.0).
It works fine the first time, and returns my single message that exists in my queue, but subsequent calls return nothing. After five minutes, the call will then return the message again.
Five minutes is the maximum lock time on a BrokeredMessage
, so I am wondering if PeekBatch
is actually locking those messages like it does on a receive, even though peeking should not lock, as far as I know.
I am trying to build an MVC view to be able to see what is actually sitting in my queue, but this one is getting in the way. Can anyone provide any guidance on this?
Update: This only seems to be happening when I cache my QueueClient
using a static property. If I create the QueueClient
fresh every time, the PeekBatch
works as expected. I still have no idea why reusing a QueueClient
causes this. Microsoft seems to recommend reusing the QueueClient
though, instead of recreating it every time, so I am still at a loss here.
By default, the message lock expires after 60 seconds. This value can be extended to 5 minutes.
Maximum delivery count The default value is 10. Whenever a message has been delivered under a peek-lock, but has been either explicitly abandoned or the lock has expired, the delivery count on the message is incremented. When the delivery count exceeds the limit, the message is moved to the DLQ.
A queue allows processing of a message by a single consumer. In contrast to queues, topics and subscriptions provide a one-to-many form of communication in a publish and subscribe pattern. It's useful for scaling to large numbers of recipients.
One of the patterns easily supported by the Azure Service Bus is the 'first-in-first-out' (FIFO) pattern – which isn't supported in the other queue service – Azure Storage Queues.
The QueueClient is being somewhat helpful. In the Peek methods (Peek and PeekBatch) you can simply call them, or you can give a specific sequence number to retrieve a specific message after a certain sequence number. If you simply call Peek, or in your case PeekBatch, without a sequence number then it will retrieve the very first message, or messages, in the queue. Once the message is returned the QueueClient keeps track of the last sequence number it pulled. Each subsequent call to Peek will fetch the next message in the queue. The idea is that you are "browsing" the messages and not just interested in the first message on the queue every time.
So, if you were in a loop and called peek repeatedly until it didn't return a message you would essentially have browsed all message in the queue.
Since you are calling PeekBatch without a sequence number the QueueClient is remembering the last set it got, then the next call would actually try to get the next set after the last message it browsed. This is why when you recreate the QueueClient it seems to reset. The reason it seemed to reset on it's own after 5 minutes seems odd, but it maybe just cleaning out the browsing values after some point that is tied to the Timeout operation on the queue. By then the sequence number would be pretty far off anyway if it was a busy queue.
If you need to really only look at the very first message then call peek only once. It will only return the first message. If you need to continually pull the first message every time do a Peek(0). If you want the first say 10 messages every time then call PeekBatch(0, 10); that will be like saying give me the first ten messages that have a sequence number greater than 0.
The guidance to reuse the QueueClient is sound. It's doing all sorts of caching of information and things. You don't want to have to recreate it each time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With