Debacle
Debacle

Reputation: 1221

Azure Service Bus Retry Policy's minbackoff doesn't work?

I'm trying to get a queue's retry logic working and I'm having an issue. the minBackoff variable doesn't seem to actually work. I see in my logs, a message gets received then fails then retries almost immediately. My minBackoff is set to 600 seconds.

Here's the code that sets up the query:

 NamespaceManager nsManager = NamespaceManager.CreateFromConnectionString(connectionString);
        nsManager.Settings.RetryPolicy = new RetryExponential(minBackoff: TimeSpan.FromSeconds(5),
                                                            maxBackoff: TimeSpan.FromSeconds(30),
                                                            maxRetryCount: 3);

        if (!nsManager.QueueExists(queueName))
        {
            nsManager.CreateQueue(queueName);
        }
        else
        {
            nsManager.DeleteQueue(queueName);
            nsManager.CreateQueue(queueName);
        }

        QueueClient client = QueueClient.CreateFromConnectionString(connectionString, queueName);


        client.RetryPolicy = new RetryExponential(minBackoff: TimeSpan.FromSeconds(15),
                                                         maxBackoff: TimeSpan.FromSeconds(600),
                                                         maxRetryCount: 3);
        for (int i = 0; i < 2000; i++)
        {
            UserCreationSubmitted creationMessage = new UserCreationSubmitted()
            {
                CreationStatus = "Step 1",
                Id = Guid.NewGuid(),
                UserName = "user number " + i,
                Userid = Guid.NewGuid()
            };

            BrokeredMessage message = new BrokeredMessage(creationMessage);
            client.Send(message);

        }

Here's the code that's not working how I think it should...

client.RetryPolicy = new RetryExponential(minBackoff: TimeSpan.FromSeconds(15),
                                                         maxBackoff: TimeSpan.FromSeconds(600),
                                                         maxRetryCount: 3);

        client.OnMessage(message =>
        {

            UserCreationSubmitted msg = message.GetBody<UserCreationSubmitted>();
            Console.WriteLine("------------------------------");
            Console.WriteLine($"Body {msg.UserName}");

            Random rnd = new Random();
            int ranNum = rnd.Next(0, 9);
            if (msg.UserName.Contains(ranNum.ToString()))
            {
                Console.WriteLine("!!!Error!!!");
                Console.WriteLine("------------------------------");
                throw new Exception();
            }
        });

Does anyone have an idea as to why the minbackoff and maxbackoff's don't seem to actually work here? Oddly enough the maxRetryCount's working like a trooper so I imagine it's definitely something in my implementation that's causing the others to not work.

Upvotes: 0

Views: 723

Answers (1)

Sean Feldman
Sean Feldman

Reputation: 26057

RetryExponential is used by ASB client for retries when a failure to receive a message is happening. In your code, exception is thrown during processing within OnMessage API callback, after the fact that message was received. OnMessage API will abandon the message, causing it to show up right away.

There a few options you could take:

  1. Clone a message, set ScheduledEnqueueTimeUtc to the delay you want, send it and then complete the original message.
  2. Defer your message, but then you can only receive it by SequenceNumber. In that case, you could create a new message with that would contain original message sequence number as a payload, schedule the new message and send it. That way you'd have the delivery count on the original message have an accurate count.

Ideally, would be nice to abandon a message with a timespan, but that's not possible with the current API.

Upvotes: 3

Related Questions