8

Is there any way to recover or delete a deferred message on Azure Service Bus if I've lost the sequence number?

The scenario is: I want to use BrokeredMessage.Defer() to defer a message. I plan to record the sequence number, and use it later on to retrieve the message. But if something goes wrong — let's say some buggy code is deployed — and the sequence number is not recorded properly, it seems like that message will sit on the service bus in a deferred state until the message expires, which could be forever.

This concerns me primarily because that message will occupy space on the queue or subscription, and I haven't found any way of recovering that space short of completely deleting the queue/subscription.

Is there any way to either receive or delete "lost" deferred messages?

Stefan Moser
  • 6,663
  • 9
  • 35
  • 48
dshpak
  • 325
  • 3
  • 6

2 Answers2

4

Peeking messages from a queue or subscription will also return deferred messages. Deferred messages will have State = "Deferred".

This way you can get the sequence numbers of the deferred messages and afterwards process or delete these messages.

You can try this out in ServiceBus Explorer:

Deferred message in ServiceBus Explorer

pberggreen
  • 928
  • 6
  • 13
  • Yes! I actually figured this out a couple months ago; thanks for adding this as a response. This is exactly what I was looking for when I asked the question. This is an especially-useful approach because deferring doesn't change the order of the messages on the queue, so the deferred messages tend to be sitting at the front of the queue, which means they're typically the first things returned by `.Peek()` or `.PeekBatch()`. – dshpak Sep 06 '17 at 12:55
2

As to preventing orphaned deferred messages because of lost sequence numbers, you should build resiliency into the storage process where you maintain them, perhaps with another queue. In other words, when you defer a message, create a message in another queue or topic to store the deferred sequence number, or the entire message (cloned).

I typically move all deferred messages to my own "deferred topic", and handle them separately. In other words, my own custom deferral logic, avoiding the problem altogether. If the auto-timeout logic does not work in your scenario (BrokeredMessage.TimeToLive), this may be a better route for you.

This article does a good job of partially explaining your scenario, using a special overload of Queue.Receive:

http://markheath.net/post/defer-processing-azure-service-bus-message

Since you are storing the sequence number (in a resilient way :-)), another alternative would be to store the entire message (JSON, property bag, etc.), and resubmit it when you want to process it again (from another queue, perhaps).

DanielG
  • 1,669
  • 1
  • 12
  • 26
  • Thanks. The approach I'm considering is, in fact, to use a queue to hold the sequence numbers, so it should be "safe". I'm thinking through the failure scenarios, such as the very simple (and unfortunately plausible) case of "my code has a bug". I'm wondering if there's any way to recover from having, say, 500 MB of messages deferred and the sequence numbers lost forever, without needing to delete a queue that's in active use by production code. Your other suggestion, of resubmitting the entire message, is precisely the other approach I'm considering :-) – dshpak Oct 25 '16 at 20:27
  • Interesting answer ;-) – Thomas Oct 26 '16 at 04:57