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:
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?
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"
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;
});