Why does BrokeredMessage.RenewLock() only renew the lock for a few seconds?
Asked Answered
E

1

8

I've got a BrokeredMessageContext class which uses a Timer to periodically check and renew the lock on a BrokeredMessage instance in case the process that handles this message runs for longer than expected. It renews the lock by calling the RenewLock() method on the BrokeredMessage instance.

I expected this call to give me a new lock with the same timeout as the original lock (MSDN states that "You can renew locks for the same duration as the entity lock timeout, and there is no maximum duration for a lock renewal."), but when debugging it appears that the lock timeout is increased by an 'arbitrary' 10-15 seconds. I've set a watch on the BrokeredMessage instance and I can see that the LockedUntilUtc propery has 10-15 seconds added to it every time I call RenewLock().

Does anyone know why this is the case? Can anything be done to renew the lock for longer?

EDIT:

Mike's answer, below, is correct. I discovered that I was, in fact, trying to renew the lock every ten seconds right from the start even though my code was intended to renew the lock now earlier than twenty seconds prior to the lock expiring. It all came down to a time comparison issue and the fact that the time on my machine was wrong (it was ahead by nearly a minute). D'oh!

Effortless answered 29/1, 2014 at 14:8 Comment(0)
P
13

When you call RenewLock it resets the time the message is locked by the LockDuration set on the Queue or Subscription the message is pulled from. If your class that is performing the renew has a timer that is firing every 10-15 seconds then the behavior you are seeing is correct.

Example: I have a queue with a lock duration of 1 minute (the default).
I pull the message at 1:20 AM UTC, so the LockedUntilUtc should read 1:21 AM UTC. If 10 seconds into the processing I call Renew lock the call fires at 1:20:10 AM, so the LockedUntilUtc would become 1:21.10 AM.

It added the lock duration value to the current time at the server, not to the previous LockedUntilUtc value. This extends your period of the lock on the message.

This answer assumes you are firing the trigger on the Timer often and not waiting to get close to the actual lock timeout. If you wanted to be more precise you could set the timer to fire about 10-20 seconds before the lock is set to expire and then do the renew lock.

Photography answered 29/1, 2014 at 15:21 Comment(7)
Hello Mike, Thanks for your answer. This does not reflect what I'm seeing. I've got a lock duration of 1 minute, and after 40 seconds I attempt to renew the lock. Still, the lock duration is only increased by 10 seconds or so.Sargasso
That is definitely odd then. I tried this quickly and the updates to the LockedUntilUtc were as expected using both the default of 1 minute as well as various other times. So based on your issue at some point I'd think the lock would run out as your timer would eventually fire "after" the amount of time being added. Are you seeing that? Also, it might help if you provide some of the code and/or timing examples?Photography
I'm going to update my question and mark your answer as accepted... After adding a lot of logging to my code I discovered that the behaviour I could see was due to a time comparison issue. Your answer is absolutely correct.Sargasso
Be careful of any direct comparisons of time between the servers and the client machines. Clock drift happens quite a bit in any hosted environment.Photography
Yep. Noted. I've re-written the lock-handler so it cares only about the duration of the lock - it doesn't rely on a comparison of server UTC time and LockedUntilUtc. Thanks Mike.Sargasso
Can't i renew the lock after the lock duration has expired ?For exammple After 5 minutes if a try to renew a lock, it says Lock has expired message!!Sexpartite
@Effortless So how did you rewrite it so it won't rely on client side time?Dermatology

© 2022 - 2024 — McMap. All rights reserved.