mirror of
https://github.com/dkam/suo.git
synced 2025-01-29 07:42:43 +00:00
Fix #initial_set which is causing a double attempt and delay on lock acquisition
The call to `#initial_set` in `#retry` and `#acquire_lock` is followed by `next` which leads to a second pass through the `#retry_with_timeout` loop and a sleep call for up to `:acquisition_delay`. This delay isn't necessary if the value can be set without a race condition. Removing the `next` call causes the client to continue to retry because the transaction has been changed outside the transaction boundary: In Redis, calling `SET` within a `WATCH`/`UNWATCH` block but not inside a `MULTI`/`EXEC` block will [cause the EXEC to fail the transaction](https://github.com/antirez/redis-doc/issues/734), so the first `#set` call fails and it requires a second pass. To resolve this I changed `#initial_set` to call `#set` within a `MULTI` block so that it would be inside the transaction. In Memcache the call to `SET` without the `CAS` during `#initial_set` is going to cause the `SET` with `CAS` to fail (return `EXISTS`), and resulting in a second pass. To resolve this I changed `#initial_set` to use `SET` with `CAS` and return the CAS value to be used in the subsequent `#set` call that stores the lock token.
This commit is contained in:
@@ -55,10 +55,7 @@ module Suo
|
||||
retry_with_timeout do
|
||||
val, cas = get
|
||||
|
||||
if val.nil?
|
||||
initial_set
|
||||
next
|
||||
end
|
||||
cas = initial_set if val.nil?
|
||||
|
||||
cleared_locks = deserialize_and_clear_locks(val)
|
||||
|
||||
@@ -101,10 +98,7 @@ module Suo
|
||||
retry_with_timeout do
|
||||
val, cas = get
|
||||
|
||||
if val.nil?
|
||||
initial_set
|
||||
next
|
||||
end
|
||||
cas = initial_set if val.nil?
|
||||
|
||||
cleared_locks = deserialize_and_clear_locks(val)
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ module Suo
|
||||
|
||||
def initial_set(val = BLANK_STR)
|
||||
@client.set(@key, val)
|
||||
_val, cas = @client.get_cas(@key)
|
||||
cas
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,7 +35,8 @@ module Suo
|
||||
end
|
||||
|
||||
def initial_set(val = BLANK_STR)
|
||||
@client.set(@key, val)
|
||||
set(val, nil)
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user