rebus-org / Rebus

:bus: Simple and lean service bus implementation for .NET
https://mookid.dk/category/rebus
Other
2.31k stars 359 forks source link

Message duplication after message lock expiration #1166

Closed RMajorczyk closed 4 months ago

RMajorczyk commented 4 months ago

Hello,

We are experiencing an issue and am unsure if it should be reported here or in the Rebus.AzureServiceBus repository.

Issue Description: When our application contacts an API that takes a long time to respond, exceeding the message lock duration configured in Azure Service Bus, we encounter message duplication. Specifically, the original message remains in the queue, and a new message is sent to the second-level retry queue. We did not have this issue in older versions of rebus (v4.0.2) with the same implementation.

Reproduction Steps: We have created a project that can reproduce this issue. The repository for this project is available here.

Setup: To run the project, a connection string needs to be set in the RebusSettings class. If needed, we can provide this information. Please feel free to contact us at rebus-issue@cubigo.com for further details or assistance.

Thank you for your help.

Best regards,

mookid8000 commented 4 months ago

Hi @RMajorczyk ,

That's how lease-based message locking works with Azure Service Bus: If a handler does not finish its work within the timeout (i.e. the duration of the lease), then it is assumed that the handler failed (and also failed to tell that it failed), and therefore the message once again becomes visible in the queue.

This is all inside Azure Service Bus (and all other queueing systems that use lease-based locking)..

If you have handlers that you know take a long time, you can make Rebus automatically renew the lease in the background by calling AutomaticallyRenewPeekLocks() on the Azure Service Bus configuration builder like so:

 t.UseAzureServiceBus(RebusSettings.ConnectionString, RebusSettings.QueueName)
    .AutomaticallyRenewPeekLocks();

When yo do this, Rebus will automatically renew the peek locks of a received message when 50% of the lease duration has elapsed.

RMajorczyk commented 3 months ago

Hi @mookid8000,

I realize I may not have provided enough details about the issue. Adding AutomaticallyRenewPeekLock() does not resolve the problem because it only seems to work if you use the maximum allowed lock duration within Azure (5 minutes).

When I use this with a lock duration of 30 seconds, the messages still keeps duplicating.

In older versions, using SimpleRetryStrategy(), this did not happen (we were using version 4.0.2 previously).

Perhaps I should report this in the Rebus.AzureServiceBus repo, but it seems like the new RetryStrategy() handles shorter message locks differently than before. Previously, when a failure occurred while closing the previous message, the second-level retry wasn't triggered. Now it is.

Thank you for your help.