5 Commits

Author SHA1 Message Date
Nick Elser
37be5ae27b bump version, update changelog 2015-04-12 20:58:18 -07:00
Nick Elser
a1a226fb59 account for variabilities in test memcached 2015-04-12 20:57:52 -07:00
Nick Elser
8d7ddaf35a move logic around loop counts to a more reasonable location 2015-04-12 20:57:29 -07:00
Nick Elser
1aacc0c1a1 properly throw lock LockClientError 2015-04-12 20:47:35 -07:00
Nick Elser
8166c6b51d specify ruby version 2015-04-12 19:53:47 -07:00
8 changed files with 33 additions and 26 deletions

View File

@@ -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).

View File

@@ -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)

View File

@@ -1,7 +0,0 @@
module Suo
module Client
module Errors
class FailedToAcquireLock < StandardError; end
end
end
end

View File

@@ -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
View File

@@ -0,0 +1,3 @@
module Suo
class LockClientError < StandardError; end
end

View File

@@ -1,3 +1,3 @@
module Suo module Suo
VERSION = "0.1.2" VERSION = "0.1.3"
end end

View File

@@ -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"

View File

@@ -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