So i'm trying to understand service bus timings... Especially how the locks works. One can choose to manually call CompleteAsync which is what we're doing. It could also be the case that the processing takes some time. In these cases we want to make sure we don't get unneccessary MessageLockLostException
.
Seems there are a couple of numbers to relate to:
Assuming the processing is running for around 2 minutes, and then either succeeds or crases (doesn't matter which case for now). Let's say this is the normal scenario, so this means that processing takes roughly 2 minutes for each message.
Also, it's indeed a queue and not a topic. And we only have one consumer that asynchronoulsy processes the messages with MaxConcurrentCalls
set to 100. We're using OnMessageAsync
with ReceiveMode.PeekLock
.
What should my settings now be as a single consumer to robustly process all messages?
I'm thinking that leaving Lock duration to 1 minute would be fine, as that's the default, and set my AutoRenewTimeout to 5 minutes for safety, because as i've understood this value should be the maximum time it takes to process a message (atleast according to this answer). Performance is not critical for this system, so i'm resonating as that leaving a message locked for some unneccessary 1, 2 or 3 minutes is not evil, as long as we don't get LockedException because these give no real value.
This thread and this thread gives great examples of how to manually renew the locks, but I thought there is a way to automatically renew the locks.
What should my settings now be as a single consumer to robustly process all messages?
Aside from LockDuration
, MaxConcurrentCalls
, AutoRenewTimeout
, and AutoComplete
there are some configurations of the Azure Service Bus client you might want to look into. For example, create not a single client with MaxConcurrentCalls
set to 100, but a few clients with total concurrency level distributed among the clients. Note that you'd want to use different MessagingFactory
instances to create those clients to ensure you have more than a single "pipe" to receive messages. And even with that, it would be way better to scale out and have competing consumers rather than having a single consumer handling all the load.
Now back to the settings. If your normal processing time is 2 minutes, it's better to set MaxLockDuration
on the entities to this time and not 1 minute. This will remove unnecessary lock extension calls to the broker and eliminate MessageLockLostException
.
Also, keep in mind that AutoRenewTimeout
is a client based operation, not broker, and therefore not guaranteed. You will run into cases where lock will be lost even though the AutoRenewTimeout
time has not elapsed yet.
AutoRenewTimeout
should always be set to longer than MaxLockDuration
as it will be counterproductive to have them equal. Have it somewhat larger than MaxLockDuration
as this is clients' "insurance" that when processing takes longer than MaxLockDuration
, message lock won't be lost. Having those two equal is, in essence, disables this fallback.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With