Search code examples
c#azureazure-functionsazureservicebusazure-webjobs

How to set Autocomplete in MessageHandlerOptions in Azure Service Bus Options (using Net Core 3.1)


I am writing a webjob using .NET Core 3.1 and my trigger looks like:

public async Task ProcessQueueMessage([ServiceBusTrigger("%ServiceBusProviderConfig:TopicName%", "%ServiceBusProviderConfig:TopicSubscriptionName%", Connection = "ServiceBusConnectionString")] Message message, MessageReceiver messageReceiver, TraceWriter log, TextWriter textWriter)

I am processing the message and calling complete / dead lettering as per the requirement in the following manner:

await messageReceiver.CompleteAsync(message.SystemProperties.LockToken);
await messageReceiver.DeadLetterAsync(message.SystemProperties.LockToken);

However, this is throwing the error: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue, or was received by a different receiver instance.

I understand that I need to somehow set the Autocomplete in MessageHandlerOptions to false for the webjob to not automatically complete it and remove from the queue.

But I am having difficulty setting this value. I tried:

  1. setting this in the appsettings.json file as follows:

    "extensions": { "serviceBus": { "messageHandlerOptions": { "maxConcurrentCalls": 16, "autoComplete": false } } }

But on running, it is not picking the settings from this file. I am not sure why, how can I make the settings be read from local config file?

  1. I also tried creating an object for MessageHandlerOptions but it the signature is missing a required param which makes it impossible to do this. Eg:

     var messageHandlerOptions = new MessageHandlerOptions(ExceptionHandler)
     {
         AutoComplete = false,
         MaxAutoRenewDuration = new TimeSpan(0, 5, 0), // 5 minutes
         MaxConcurrentCalls = 1,
     };
    
    messageReceiver.RegisterMessageHandler(MessageProcessor, messageHandlerOptions);
    

    static async Task MessageProcessor(Message message, CancellationToken token) { await messageReceiver.CompleteAsync(message.SystemProperties.LockToken); }

I am unable to access messageReceiver within MessageProcessor and thats why this is not possible too.

Can anyone please suggest how I can set ServiceBusOptions in a config file to be read at runtime?

FYI, I am using the following packages:

1. Microsoft.Azure.ServiceBus Version="4.1.3"
2. Microsoft.Azure.WebJobs.Extensions Version="3.0.0"
3. Microsoft.Azure.WebJobs.Extensions.ServiceBus Version="3.0.0"
4. Microsoft.Azure.WebJobs.Extensions.Storage Version="4.0.2"
5. Microsoft.Azure.WebJobs.Logging.ApplicationInsights Version="3.0.14"

Solution

  • After a lot of searching, finally found the answer. Posting it for anyone looking for the same question:

        services.AddServiceBus(options =>
        {
            options.ConnectionString = "ServiceBusConnectionString";
            options.MessageHandlerOptions.AutoComplete = false;
            options.PrefetchCount = 1;
            options.MessageHandlerOptions.MaxConcurrentCalls = 1;
        });