Daniel Moreira
Daniel Moreira

Reputation: 25

Azure service Bus Exception on trye to complete message

I'm using the GitHub example to process the messages of a topic:

private void RegisterSubscriptionClientMessageHandler()
{
    _subscriptionClient.RegisterMessageHandler(
        async (message, token) =>
        {
            var eventName = $"{message.Label}{INTEGRATION_EVENT_SUFIX}";
            var messageData = Encoding.UTF8.GetString(message.Body);
            await ProcessEvent(eventName, messageData);
                    
            // Complete the message so that it is not received again.
            await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
        },
        new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 10, AutoComplete = false });
}

All messages are sent and received by all subscribers successfully, however in the command:

await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);

The following error always occurs:

 ERROR ON ExceptionReceivedHandler EXEPTION: 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.
Bazinga.EventBus.Bus.EventBusSubscription:Error: ERROR ON ExceptionReceivedHandler EXEPTION: 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.
- Executing Action: UserCallback

Any tips on how to solve? Thank you!

Upvotes: 1

Views: 4285

Answers (2)

Jayendran
Jayendran

Reputation: 10910

The other main reason for this will be Autocomplete is enabled by default.

Whenever you are using CompleteAsync() then you should also instantiate an OnMessageOptions object in order to set the set AutoComplete to false, and pass it into your OnMessage call.

OnMessageOptions onMessageOpt = new OnMessageOptions();
onMessageOpt.AutoComplete = false;

client.OnMessage(processCalculations, options);

See this Similar SO Solution

Upvotes: 1

Arunprabhu
Arunprabhu

Reputation: 1494

When a message is received from Service Bus Queue or Topic Subscription, a lock token will be returned with the message.

The lock token can be used to delete, dead letter or defer a message.

Every Queue and Topic Subscription has Lock duration property with it. Based on the time span configured for Lock duration, the lock supplied with the message will be expired.

Here, you are doing some processing await ProcessEvent(eventName, messageData); before completing the message.

The problem must be the the lock gets expired before_subscriptionClient.CompleteAsync(message.SystemProperties.LockToken); line is executed.

Increasing the lock duration or completing the message before calling ProcessEvent will solve your problem.

Upvotes: 1

Related Questions