mirror of
https://github.com/dkam/suo.git
synced 2025-01-29 07:42:43 +00:00
fix documentation and add another test for refresh
This commit is contained in:
27
README.md
27
README.md
@@ -41,16 +41,35 @@ Thread.new { suo.lock("other_key", 2) { puts "Three" } }
|
|||||||
suo = Suo::Client::Memcached.new(client: some_dalli_client, acquisition_timeout: 1) # in seconds
|
suo = Suo::Client::Memcached.new(client: some_dalli_client, acquisition_timeout: 1) # in seconds
|
||||||
|
|
||||||
# manually locking/unlocking
|
# manually locking/unlocking
|
||||||
suo.lock("a_key")
|
# the return value from lock without a block is a unique token valid only for the current lock
|
||||||
|
# which must be unlocked manually
|
||||||
|
lock = suo.lock("a_key")
|
||||||
foo.baz!
|
foo.baz!
|
||||||
suo.unlock("a_key")
|
suo.unlock("a_key", lock)
|
||||||
|
|
||||||
# custom stale lock cleanup (cleaning of dead clients)
|
# custom stale lock expiration (cleaning of dead locks)
|
||||||
suo = Suo::Client::Redis.new(client: some_redis_client, stale_lock_expiration: 60*5)
|
suo = Suo::Client::Redis.new(client: some_redis_client, stale_lock_expiration: 60*5)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Stale locks
|
||||||
|
|
||||||
|
"Stale locks" - those acquired more than `stale_lock_expiration` (defaulting to 3600 or one hour) ago - are automatically cleared during any operation on the key (`lock`, `unlock`, `refresh`). The `locked?` method will not return true if only stale locks exist, but will not modify the key itself.
|
||||||
|
|
||||||
|
To re-acquire a lock in the middle of a block, you can use the refresh method on client.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
suo = Suo::Client::Redis.new
|
||||||
|
|
||||||
|
# lock is the same token as seen in the manual example, above
|
||||||
|
suo.lock("foo") do |lock|
|
||||||
|
5.times do
|
||||||
|
baz.bar!
|
||||||
|
suo.refresh("foo", lock)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- better stale key handling (refresh blocks)
|
|
||||||
- more race condition tests
|
- more race condition tests
|
||||||
|
|
||||||
## History
|
## History
|
||||||
|
|||||||
@@ -191,6 +191,38 @@ module ClientTests
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_refresh
|
def test_refresh
|
||||||
|
client = client(stale_lock_expiration: 0.5)
|
||||||
|
|
||||||
|
lock1 = client.lock(TEST_KEY)
|
||||||
|
|
||||||
|
assert_equal true, client.locked?(TEST_KEY)
|
||||||
|
|
||||||
|
client.refresh(TEST_KEY, lock1)
|
||||||
|
|
||||||
|
assert_equal true, client.locked?(TEST_KEY)
|
||||||
|
|
||||||
|
sleep 0.55
|
||||||
|
|
||||||
|
assert_equal false, client.locked?(TEST_KEY)
|
||||||
|
|
||||||
|
lock2 = client.lock(TEST_KEY)
|
||||||
|
|
||||||
|
client.refresh(TEST_KEY, lock1)
|
||||||
|
|
||||||
|
assert_equal true, client.locked?(TEST_KEY)
|
||||||
|
|
||||||
|
client.unlock(TEST_KEY, lock1)
|
||||||
|
|
||||||
|
# edge case with refresh lock in the middle
|
||||||
|
assert_equal true, client.locked?(TEST_KEY)
|
||||||
|
|
||||||
|
client.unlock(TEST_KEY, lock2)
|
||||||
|
|
||||||
|
# now finally unlocked
|
||||||
|
assert_equal false, client.locked?(TEST_KEY)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_block_refresh
|
||||||
success_counter = Queue.new
|
success_counter = Queue.new
|
||||||
failure_counter = Queue.new
|
failure_counter = Queue.new
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user