2

Problem: I need to reschedule/defer a message to be processed after a user defined elapsed time as the receiver.

Goal: After a HttpReponseException of ServerUnavailable, I would like to retry processing of the message after 30 minutes. It must also follow the rule set being after 10 delivery attempts the message is sent to the dead letter queue (Happens automatically based on the topic rules).

So I have a function app to process a Azure Service Bus Topic. This means that thread sleeping is not an option.

What I have tried:

  1. I understand messageSender.ScheduleMessageAsync(message, dateTime) is used on the senders side to schedule the message for later processing which works when sending a new message, however, I as the receiver would like to do this on my side after getting an exception.
  2. I tried using messageReceiver.DeferAsync(message.SystemProperties.LockToken, properties), properties containing the new "ScheduledEnqueueTimeUtc" and this does defer the message but the Sequence ID's seem to go out of sync making it impossible to receive my deferred message.
  3. If I clone the message I cannot set the SystemProperty.DeliveryCount as it is readonly hence the Dead Letter Queue Rule will not function as intended. I can create UserProperty's and manually count message reties and a scheduled date in my function app but I am wondering if there is a better way to do this?

Any suggestions will be appriciated.

Rishal92
  • 36
  • 5

2 Answers2

0

What do you think about creating a retry policy ? and instead of thread.sleep you can shedule the same message another time in the queue but with specific time +30 minutes , and returning postive response to clear the currentmessage,

you need to keep the rule of deliveryCount , so you may need to add property to the message queue that have a count?

i think this idea is logic , here is article that may help you , you need to jsut change thread.sleep with ScheduleMessageAsync

Houssem
  • 1,042
  • 7
  • 16
  • Thanks for this suggestion. Since I am using a function app the minute I update the cloned message and resend it with an attempt increment it is firing again but this time around it does not process the retry attempt as it suppose to and completes the messages. Seem like the async nature of the function app is throwing me for a loop. – Rishal92 Sep 01 '20 at 15:07
  • if i understand you correctly you are worried about the retry counter that it will reset to zero at every send , and that's why i suggest that you create your custom counter(property) that it's sended with the object/model of the message in the queue. – Houssem Sep 02 '20 at 12:55
  • So go with option 3 from what I listed? I guess I can write a helper class to do that and reuse that custom retry handler and pass in the rules. Really thought there would be an easier way. I will share the custom solution here. – Rishal92 Sep 03 '20 at 10:53
  • Thank you for pointing me in the right direction Houssem. I have updated my solution. – Rishal92 Sep 04 '20 at 12:49
0

I managed to resolve retrying a message using custom UserProperties.

This is in line with what Houssem Dbira suggested and my 3rd point but instead of using a custom retry policy object I created a helper function that manages the retry count as well as schedules the message again to the service bus.

The link below will take you to the helper function I created if you interested in doing this yourself.

RetryHelper.cs

Rishal92
  • 36
  • 5