Reputation: 133
I have implemented a service bus trigger, my sample code is as below.
public static async Task Run([ServiceBusTrigger("myqueue", Connection =
"myservicebus:cs")]BrokeredMessage myQueueItem, TraceWriter log)
{
try
{
if (myQueueItem.LockedUntilUtc <= DateTime.UtcNow)
{
log.Info($"Lock expired.");
return;
}
//renew lock if message lock is about to expire.
if ((myQueueItem.LockedUntilUtc - DateTime.UtcNow).TotalSeconds <= defaultLock)
{
await myQueueItem.RenewLockAsync();
return true;
}
//Process message logic
await myQueueItem.CompleteAsync();
}
catch (MessageLockLostException ex)
{
log.Error($"Message Lock lost. Exception: {ex}");
}
catch(CustomException ex)
{
//forcefully dead letter if custom exception occurs
await myQueueItem.DeadLetterAsync();
}
catch (Exception ex)
{
log.Error($"Error occurred while processing message. Exception: {ex}");
await myQueueItem.AbandonAsync();
}
}
I have set the default lock duration on the queue as 5 minutes. I'm getting message lock lost exception for few requests, even though lock was actually not expired. Request process timings as below:
Can anybody help me to find actually what is wrong with my code. Thanks.
Upvotes: 0
Views: 3408
Reputation: 35124
You should not explicitly call CompleteAsync
and AbandonAsync
in your code. Those methods will be called by Azure Functions runtime automatically based on the result of your function execution (Complete
if no exception occurred, Abandon
otherwise).
Renewing the lock manually shouldn't be necessary either, runtime should manage that for you. If you are running on Consumption plan, the max duration of function execution is 5 minutes (by default) anyway.
Try removing all the plumbing code and leave only //Process message logic
, see if that helps.
Upvotes: 4