4

I have several WebJobs with ServiceBus triggers, and I have a custom MessageProcessor to do some processing after the message has finished processing.

I'd like to be able to do something different (specifically, log an Error instead of a Warning) if the message is on its last retry, i.e. it's just about to be sent to the deadletter queue. The BrokeredMessage sent into the CompleteProcessingMessageAsync function has the DeliveryCount, but I can't see a way to get back to the original queue to find the MaxDeliveryCount. Any ideas? Different queues have different MaxDeliveryCounts, so setting a constant isn't really an option. The only other thing I can think of is to create a separate job for each queue's dead letter queue, but I'd like to be able to do it at the WebJob level rather than for each individual job.

public class CustomMessageProcessor : MessageProcessor
{
    public CustomMessageProcessor(OnMessageOptions messageOptions) : base(messageOptions)
    {
    }

    public override async Task CompleteProcessingMessageAsync(BrokeredMessage message, FunctionResult result, CancellationToken cancellationToken)
    {
        if (result.Succeeded)
        {
            if (!MessageOptions.AutoComplete)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await message.CompleteAsync();
            }
        }
        else
        {
            cancellationToken.ThrowIfCancellationRequested();

            //some other processing

            //If message.DeliveryCount < maxDeliveryCount 
            //  log warning
            //else
            //  log error

            await message.AbandonAsync();
        }
    }
}
Anthony Keenan
  • 166
  • 2
  • 8

2 Answers2

1

You should be able to obtain Microsoft.ServiceBus.Messaging.QueueDescription from the parent queue, and then use MaxDeliveryCount off it. The only thing is that getting queue description is a relatively expensive operation, so I'd recommend doing it once initially, and cache the value for each queue.

Slava Asipenko
  • 392
  • 1
  • 3
  • But how do I work out which queue the message came from? – Anthony Keenan Jun 27 '17 at 08:58
  • @anthony-keenan it depends - how do you wire up your custom message processor? Do you know which processor instance binds to which queue? I don't have direct experience with this part of the SDK, but my understanding is when custom message processors are wired up (for example via messaging provider) you should see something like "entity path" - if yes you should pass it onto your processor instance, and then use to reference a queue in a cached / shared collection. – Slava Asipenko Jun 27 '17 at 13:56
  • The custom message processor overrides the one that is part of the Webjobs framework. It is invoked before and after every message the webjob processes, unfortunately, it's global, not queue specific, and from what I can see the queue path isn't on the brokered message, so I can't lookup the queue from there. – Anthony Keenan Jun 28 '17 at 11:23
0

Different queues have different MaxDeliveryCounts, so setting a constant isn't really an option

As Slava Asipenko mentioned that we could set MaxDeliveryCount for servicebus queue.

how do I work out which queue the message came from

We could get the message properties to know the queue name if we set it during sending. Take Label for example:

var message = new BrokeredMessage(object);
message.Label = "queue name";
client.Send(message);
Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
  • The messages I am processing are actually published via a Topic. So you could set the Topic name on the send side as a message label, however the MaxDeliveryCount is Queue specific, and you wouldn't know which queue it was being processed from. This also seems messy, changing the send side to make up for a receive side deficiency. – Anthony Keenan Jun 29 '17 at 13:53
  • We also could set [MaxDeliveryCount](https://learn.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.subscriptiondescription.maxdeliverycount?view=azure-dotnet#Microsoft_ServiceBus_Messaging_SubscriptionDescription_MaxDeliveryCount) for subcription . We also could add properties for message, for example, `message.Properties["subcriptionName"] = "subscription name"`; – Tom Sun - MSFT Jun 30 '17 at 05:09