0
votes

I'm trying to use the ServiceBus subscriptions's MaxDeliveryCount for implementing retry of message processing. Not sure it's the best idea, but don't want to lose messages.

Scenario:

  1. Having one topic, with two subscribers one sending (A) and the other (B) receiving messages, using Peek-Lock
  2. Both subscriptions have configured MaxDeliveryCount=10
  3. Both clients use SubscriptionClient.ReceiveBatch(50,TimeSpan.FromMilliseconds(50)) to get the messages from the Queue
  4. A sends 5 messages, having payload "1", "2",..."5"
  5. The first messages ("1") fails to process on B and is marked as abandoned (BrokeredMessage.Abandon())

    Reason: for internal reasons, app can't process this message now.

    It's not yet BlackLettered since DeliveryCount < MaxDeliveryCount)

  6. Next, since the message "1" previously failed, only one message is requested from, and it's expected to be message "1" SubscriptionClient.ReceiveBatch(1,TimeSpan.FromMilliseconds(50))
  7. After 2-3 repetitions of step 7, instead of receiving message "1", message "2" is received Message "2" is also marked as Abandoned since message "1" is expected
  8. Then message "3" is received
    Message "3" is also marked as Abandoned since message "1" is expected

    and so on.

It seems, in this scenario, the SB is delivering the messages in a Round Robing manner.

Is this the intended behavior of ServiceBus?

I am aware about the existence of some debates whether SB guarantees ordered delivery or not. For the applications it's really important that messages are processed in the same order they are sent.

Any ideas how reprocessing of message "1" could be performed until DeliveryCount reaches MaxDeliveryCount before processing the message "2"?

1
It seems, this behavior is related to prefetching! docs.microsoft.com/en-us/azure/service-bus-messaging/… : "if the client initiates a receive operation and the cache contains a message, the message is taken from the cache."Adam Bartha
Have you seen this post: stackoverflow.com/questions/28702033/… ?Thomas
Any updates? Do you solve the problem?Fei Han
I've set the PrefetchCount to 0 for the SubscriptionClient and use ReceiveBatch(50) for polling.Adam Bartha

1 Answers

0
votes

Firstly, as Thomas shared in his comment, you could try to specify SupportOrdering property to true for the Topic.

TopicDescription td = new TopicDescription("TopicTest");
td.SupportOrdering = true;

And if subscription client received a message and call Abandon method to abandon the lock on a peek-locked message, we could call Receive method again to get it again, like this.

enter image description here

output:

enter image description here

On the other hand, if possible, you could try to combine a complete work steps with a specific order in a single message instead of splitting steps in multiple messages, and then you could control the processing in specific order in your code logic rather than reply on the service bus infrastructure to provide this guarantee.