mirror of
https://github.com/dkam/suo.git
synced 2025-01-29 07:42:43 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37be5ae27b | ||
|
|
a1a226fb59 | ||
|
|
8d7ddaf35a | ||
|
|
1aacc0c1a1 | ||
|
|
8166c6b51d |
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.1.3
|
||||||
|
|
||||||
|
- Properly throw Suo::LockClientError when the connection itself fails (Memcache server not reachable, etc.)
|
||||||
|
|
||||||
## 0.1.2
|
## 0.1.2
|
||||||
|
|
||||||
- Fix retry_timeout to properly use the full time (was being calculated incorrectly).
|
- Fix retry_timeout to properly use the full time (was being calculated incorrectly).
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module Suo
|
module Suo
|
||||||
module Client
|
module Client
|
||||||
class Base
|
class Base
|
||||||
|
|
||||||
DEFAULT_OPTIONS = {
|
DEFAULT_OPTIONS = {
|
||||||
retry_timeout: 0.1,
|
retry_timeout: 0.1,
|
||||||
retry_delay: 0.01,
|
retry_delay: 0.01,
|
||||||
@@ -111,7 +112,7 @@ module Suo
|
|||||||
break unless acquisition_lock
|
break unless acquisition_lock
|
||||||
break if set(key, serialize_locks(locks), cas, options)
|
break if set(key, serialize_locks(locks), cas, options)
|
||||||
end
|
end
|
||||||
rescue FailedToAcquireLock => _ # rubocop:disable Lint/HandleExceptions
|
rescue LockClientError => _ # rubocop:disable Lint/HandleExceptions
|
||||||
# ignore - assume success due to optimistic locking
|
# ignore - assume success due to optimistic locking
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -124,8 +125,6 @@ module Suo
|
|||||||
|
|
||||||
fail "Client required" unless options[:client]
|
fail "Client required" unless options[:client]
|
||||||
|
|
||||||
options[:retry_count] = (options[:retry_timeout] / options[:retry_delay].to_f).ceil
|
|
||||||
|
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -148,13 +147,13 @@ module Suo
|
|||||||
end
|
end
|
||||||
|
|
||||||
def retry_with_timeout(key, options)
|
def retry_with_timeout(key, options)
|
||||||
|
count = (options[:retry_timeout] / options[:retry_delay].to_f).ceil
|
||||||
|
|
||||||
start = Time.now.to_f
|
start = Time.now.to_f
|
||||||
|
|
||||||
options[:retry_count].times do
|
count.times do
|
||||||
if options[:retry_timeout]
|
now = Time.now.to_f
|
||||||
now = Time.now.to_f
|
break if now - start > options[:retry_timeout]
|
||||||
break if now - start > options[:retry_timeout]
|
|
||||||
end
|
|
||||||
|
|
||||||
synchronize(key, options) do
|
synchronize(key, options) do
|
||||||
yield
|
yield
|
||||||
@@ -163,7 +162,7 @@ module Suo
|
|||||||
sleep(rand(options[:retry_delay] * 1000).to_f / 1000)
|
sleep(rand(options[:retry_delay] * 1000).to_f / 1000)
|
||||||
end
|
end
|
||||||
rescue => _
|
rescue => _
|
||||||
raise FailedToAcquireLock
|
raise LockClientError
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize_locks(locks)
|
def serialize_locks(locks)
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
module Suo
|
|
||||||
module Client
|
|
||||||
module Errors
|
|
||||||
class FailedToAcquireLock < StandardError; end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -8,7 +8,7 @@ require "redis"
|
|||||||
|
|
||||||
require "msgpack"
|
require "msgpack"
|
||||||
|
|
||||||
require "suo/client/errors"
|
require "suo/errors"
|
||||||
require "suo/client/base"
|
require "suo/client/base"
|
||||||
require "suo/client/memcached"
|
require "suo/client/memcached"
|
||||||
require "suo/client/redis"
|
require "suo/client/redis"
|
||||||
|
|||||||
3
lib/suo/errors.rb
Normal file
3
lib/suo/errors.rb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module Suo
|
||||||
|
class LockClientError < StandardError; end
|
||||||
|
end
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
module Suo
|
module Suo
|
||||||
VERSION = "0.1.2"
|
VERSION = "0.1.3"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|||||||
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
||||||
spec.require_paths = ["lib"]
|
spec.require_paths = ["lib"]
|
||||||
|
|
||||||
|
spec.required_ruby_version = "~> 2.0"
|
||||||
|
|
||||||
spec.add_dependency "dalli"
|
spec.add_dependency "dalli"
|
||||||
spec.add_dependency "redis"
|
spec.add_dependency "redis"
|
||||||
spec.add_dependency "msgpack"
|
spec.add_dependency "msgpack"
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ module ClientTests
|
|||||||
assert_equal "Client required", exception.message
|
assert_equal "Client required", exception.message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_throws_failed_error_on_bad_client
|
||||||
|
assert_raises(Suo::LockClientError) do
|
||||||
|
@klass.lock(TEST_KEY, 1, client: {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_class_single_resource_locking
|
def test_class_single_resource_locking
|
||||||
lock1 = @klass.lock(TEST_KEY, 1, client: @klass_client)
|
lock1 = @klass.lock(TEST_KEY, 1, client: @klass_client)
|
||||||
refute_nil lock1
|
refute_nil lock1
|
||||||
@@ -73,10 +79,10 @@ module ClientTests
|
|||||||
success_counter = Queue.new
|
success_counter = Queue.new
|
||||||
failure_counter = Queue.new
|
failure_counter = Queue.new
|
||||||
|
|
||||||
100.times.map do |i|
|
50.times.map do |i|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
success = @client.lock(TEST_KEY, 50, retry_timeout: 0.5) do
|
success = @client.lock(TEST_KEY, 25, retry_timeout: 0.9) do
|
||||||
sleep(2)
|
sleep(3)
|
||||||
success_counter << i
|
success_counter << i
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -84,17 +90,17 @@ module ClientTests
|
|||||||
end
|
end
|
||||||
end.map(&:join)
|
end.map(&:join)
|
||||||
|
|
||||||
assert_equal 50, success_counter.size
|
assert_equal 25, success_counter.size
|
||||||
assert_equal 50, failure_counter.size
|
assert_equal 25, failure_counter.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_instance_multiple_resource_locking_longer_timeout
|
def test_instance_multiple_resource_locking_longer_timeout
|
||||||
success_counter = Queue.new
|
success_counter = Queue.new
|
||||||
failure_counter = Queue.new
|
failure_counter = Queue.new
|
||||||
|
|
||||||
100.times.map do |i|
|
50.times.map do |i|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
success = @client.lock(TEST_KEY, 50, retry_timeout: 2) do
|
success = @client.lock(TEST_KEY, 25, retry_timeout: 2) do
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
success_counter << i
|
success_counter << i
|
||||||
end
|
end
|
||||||
@@ -103,7 +109,7 @@ module ClientTests
|
|||||||
end
|
end
|
||||||
end.map(&:join)
|
end.map(&:join)
|
||||||
|
|
||||||
assert_equal 100, success_counter.size
|
assert_equal 50, success_counter.size
|
||||||
assert_equal 0, failure_counter.size
|
assert_equal 0, failure_counter.size
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user