redis-em-mutex 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ 0.1.2
2
+ - features macro-style definitions
3
+ - fixed: setup with :redis
4
+ - added macros spec
5
+ - added more setup features spec
6
+
1
7
  0.1.1
2
8
  - fixed: namespaces didn't work
3
9
  - added namespaces spec
data/README.rdoc CHANGED
@@ -20,6 +20,7 @@ Author:: Rafał Michalski (mailto:rafal@yeondir.com)
20
20
  * fiber-safe
21
21
  * deadlock detection (only trivial cases: locking twice the same resource from the same fiber)
22
22
  * mandatory lock expiration (with refreshing)
23
+ * macro-style definitions (Mutex::Macro mixin)
23
24
 
24
25
  == BUGS/LIMITATIONS
25
26
 
@@ -31,8 +32,8 @@ Author:: Rafał Michalski (mailto:rafal@yeondir.com)
31
32
  == REQUIREMENTS
32
33
 
33
34
  * ruby >= 1.9 (tested: 1.9.3-p194, 1.9.2-p320, 1.9.1-p378)
34
- * http://github.com/redis/redis-rb >= 3.0.1
35
- * http://rubyeventmachine.com >= 0.12.10
35
+ * http://github.com/redis/redis-rb ~> 3.0.1
36
+ * http://rubyeventmachine.com ~> 1.0.0
36
37
  * (optional) http://github.com/igrigorik/em-synchrony
37
38
 
38
39
  == INSTALL
@@ -41,7 +42,7 @@ Author:: Rafał Michalski (mailto:rafal@yeondir.com)
41
42
 
42
43
  ==== Gemfile
43
44
 
44
- gem "redis-em-mutex", "~> 0.1.1"
45
+ gem "redis-em-mutex", "~> 0.1.2"
45
46
 
46
47
  ==== Github
47
48
 
@@ -100,7 +101,7 @@ Author:: Rafał Michalski (mailto:rafal@yeondir.com)
100
101
 
101
102
  EM.synchrony do
102
103
  ns.synchronize('foo') do
103
- .... do something with foo and bar
104
+ .... do something with foo
104
105
  end
105
106
  ...
106
107
  EM.stop
@@ -140,6 +141,54 @@ Author:: Rafał Michalski (mailto:rafal@yeondir.com)
140
141
  EM.stop
141
142
  end
142
143
 
144
+ === Macro-style definition
145
+
146
+ Borrowed from http://github.com/kenn/redis-mutex.
147
+ Redis::EM::Mutex::Macro is a mixin which protects selected instance methods of a class with a mutex.
148
+ The locking scope will be Mutex global namespace + class name + method name.
149
+
150
+ class TheClass
151
+ include Redis::EM::Mutex::Macro
152
+
153
+ auto_mutex
154
+ def critical_run
155
+ ... do some critical stuff
156
+ ....only one fiber in one process on one machine is executing this instance method of any instance of defined class
157
+ end
158
+
159
+ auto_mutex expire: 100, ns: '**TheClass**'
160
+ # all critical methods defined later will inherit above options unless overridden
161
+
162
+ auto_mutex # start and stop will be protected
163
+ def start
164
+ ...
165
+ end
166
+
167
+ def stop
168
+ ...
169
+ end
170
+
171
+ no_auto_mutex
172
+ def some_unprotected_method
173
+ ...
174
+ end
175
+
176
+ auto_mutex :run_long, expire: 100000, block: 10, on_timeout: :cant_run
177
+ def run_long
178
+ ...
179
+ end
180
+
181
+ def cant_run
182
+ ...
183
+ end
184
+
185
+ def foo
186
+ ...
187
+ end
188
+ auto_mutex :foo, block: 0, on_timeout: proc { puts 'bar!' }
189
+
190
+ end
191
+
143
192
  === Advanced
144
193
 
145
194
  mutex = Redis::EM::Mutex.new('resource1', 'resource2', expire: 60)
data/Rakefile CHANGED
@@ -6,7 +6,9 @@ $gem_name = "redis-em-mutex"
6
6
 
7
7
  desc "Run spec tests"
8
8
  task :test do
9
- sh "rspec spec/*.rb"
9
+ Dir["spec/#{$gem_name}-*.rb"].each do |spec|
10
+ sh "rspec #{spec}"
11
+ end
10
12
  end
11
13
 
12
14
  desc "Build the gem"
@@ -0,0 +1,123 @@
1
+ class Redis
2
+ module EM
3
+ class Mutex
4
+ # Macro-style definition
5
+ #
6
+ # idea and some code borrowed from http://github.com/kenn/redis-mutex and enhanced
7
+ #
8
+ # class ClassWithCriticalMethods
9
+ # include Redis::EM::Mutex::Macro
10
+ #
11
+ # auto_mutex
12
+ # def critical
13
+ # ... do some critical stuff
14
+ # ....only one fiber in one process on one machine is executing this instance method of any instance of defined class
15
+ # end
16
+ # end
17
+ #
18
+ module Macro
19
+ def self.included(klass)
20
+ klass.extend ClassMethods
21
+ klass.class_eval do
22
+ class << self
23
+ attr_reader :auto_mutex_methods, :auto_mutex_options
24
+ attr_accessor :auto_mutex_enabled
25
+ end
26
+ @auto_mutex_methods = {}
27
+ @auto_mutex_options = {:ns => Redis::EM::Mutex.ns ? "#{Redis::EM::Mutex.ns}:#{klass.name}" : klass.name}
28
+ @auto_mutex_enabled = false
29
+ end
30
+ end
31
+
32
+ module ClassMethods
33
+ # auto_mutex [*method_names], [options]
34
+ #
35
+ # options are:
36
+ # - :expire - see Mutex.new
37
+ # - :block - see Mutex.new
38
+ # - :ns - custom namespace, if not present name of the class that includes Macro is used
39
+ # - :on_timeout - if defined, this proc/method will be called instead of raising MutexTimeout error
40
+ #
41
+ # If method_names are provided (names of already defined methods or defined in the future)
42
+ # they become protected with mutex.
43
+ #
44
+ # If options are provided wihout method_names, they will become default options
45
+ # for subsequent auto_mutex calls.
46
+ #
47
+ # If auto_mutex is called without arguments then any method further defined will also be protected.
48
+ # To disable implicit auto_mutex use no_auto_mutex.
49
+ def auto_mutex(*args)
50
+ options = args.last.kind_of?(Hash) ? args.pop : {}
51
+ if args.each {|target|
52
+ self.auto_mutex_methods[target] = self.auto_mutex_options.merge(options)
53
+ auto_mutex_method_added(target) if method_defined? target
54
+ }.empty?
55
+ if options.empty?
56
+ self.auto_mutex_enabled = true
57
+ else
58
+ self.auto_mutex_options.update(options)
59
+ end
60
+ end
61
+ end
62
+
63
+ # Switch off implicit auto_mutex.
64
+ # After calling no_auto_mutex if any new method is defined it won't be protected
65
+ # unless explicitely specified with auto_mutex.
66
+ def no_auto_mutex
67
+ self.auto_mutex_enabled = false
68
+ end
69
+
70
+ def method_added(target)
71
+ return if target.to_s =~ /_(?:with|without|on_timeout)_auto_mutex$/
72
+ return unless self.auto_mutex_methods[target] || self.auto_mutex_enabled
73
+ auto_mutex_method_added(target)
74
+ end
75
+
76
+ def auto_mutex_method_added(target)
77
+ without_method = "#{target}_without_auto_mutex"
78
+ with_method = "#{target}_with_auto_mutex"
79
+ timeout_method = "#{target}_on_timeout_auto_mutex"
80
+ return if method_defined?(without_method)
81
+
82
+ options = self.auto_mutex_methods[target] || self.auto_mutex_options
83
+ mutex = nil
84
+
85
+ on_timeout = options[:on_timeout] || options[:after_failure]
86
+
87
+ if on_timeout.respond_to?(:call)
88
+ define_method(timeout_method, &on_timeout)
89
+ elsif on_timeout.is_a?(Symbol)
90
+ timeout_method = on_timeout
91
+ end
92
+
93
+ define_method(with_method) do |*args, &blk|
94
+ mutex||= Redis::EM::Mutex.new target, options
95
+ response = nil
96
+
97
+ begin
98
+ if mutex.refresh
99
+ response = __send__(without_method, *args, &blk)
100
+ else
101
+ mutex.synchronize do
102
+ response = __send__(without_method, *args, &blk)
103
+ end
104
+ end
105
+ rescue Redis::EM::Mutex::MutexTimeout => e
106
+ if respond_to?(timeout_method)
107
+ response = __send__(timeout_method, *args, &blk)
108
+ else
109
+ raise e
110
+ end
111
+ end
112
+
113
+ response
114
+ end
115
+
116
+ alias_method without_method, target
117
+ alias_method target, with_method
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,7 @@
1
+ class Redis
2
+ module EM
3
+ class Mutex
4
+ VERSION = '0.1.2'
5
+ end
6
+ end
7
+ end
@@ -3,6 +3,7 @@ require 'ostruct'
3
3
  require 'securerandom'
4
4
  require 'redis/connection/synchrony' unless defined? Redis::Connection::Synchrony
5
5
  require 'redis'
6
+ require 'redis/em-mutex/version'
6
7
 
7
8
  class Redis
8
9
  module EM
@@ -13,12 +14,15 @@ class Redis
13
14
  # Methods of this class are NOT thread-safe.
14
15
  # They are machine/process/fiber-safe.
15
16
  # All method calls must be invoked only from EventMachine's reactor thread.
17
+ # Wrap mutex calls in EventMachine.shedule from non-reactor threads.
16
18
  #
17
19
  # - The terms "lock" and "semaphore" used in documentation are synonims.
18
- # - The term "owner" denotes a Ruby Fiber in some Process on some Machine.
20
+ # - The term "owner" denotes a Ruby Fiber executing code in the scope of Machine/Process/Fiber
21
+ # possessing exclusively a named semaphore(s).
19
22
  #
20
23
  class Mutex
21
- VERSION = '0.1.1'
24
+
25
+ autoload :Macro, 'redis/em-mutex/macro'
22
26
 
23
27
  module Errors
24
28
  class MutexError < RuntimeError; end
@@ -125,7 +129,8 @@ class Redis
125
129
  end
126
130
  end
127
131
 
128
- # Returns `true` if this semaphore (all the locked `names`) is currently being held by calling fiber.
132
+ # Returns `true` if this semaphore (all the locked `names`) is currently being held by calling fiber
133
+ # (if executing fiber is the owner).
129
134
  def owned?
130
135
  !!if @locked_id
131
136
  lock_full_ident = owner_ident(@locked_id)
@@ -360,7 +365,7 @@ class Redis
360
365
  }.reject {|_k, v| v.nil?})
361
366
  end
362
367
  if (redis = opts.redis) && !opts.url
363
- redis_updater.call redis
368
+ redis_updater.call redis.client
364
369
  elsif opts.url
365
370
  redis_options[:url] = opts.url
366
371
  end
@@ -1,5 +1,9 @@
1
- class Redis
2
- module EM
3
- autoload :Mutex, 'redis/em-mutex'
1
+ if defined?(Redis::EM::Mutex)
2
+ require 'redis/em-mutex'
3
+ else
4
+ class Redis
5
+ module EM
6
+ autoload :Mutex, 'redis/em-mutex'
7
+ end
4
8
  end
5
9
  end
@@ -1,5 +1,5 @@
1
1
  $:.unshift "lib"
2
- require 'redis/em-mutex'
2
+ require 'redis/em-mutex/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "redis-em-mutex"
@@ -18,11 +18,11 @@ Gem::Specification.new do |s|
18
18
  "--main" << "README.rdoc"
19
19
  s.has_rdoc = true
20
20
  s.extra_rdoc_files = ["README.rdoc"]
21
- s.requirements << "Redis server"
22
- s.add_runtime_dependency "redis", ">= 3.0.0"
21
+ s.requirements << "Redis server 2.4+"
22
+ s.add_runtime_dependency "redis", ">= 3.0.1"
23
23
  s.add_runtime_dependency "hiredis", "~> 0.4.5"
24
- s.add_runtime_dependency "eventmachine", ">= 0.12.10"
24
+ s.add_runtime_dependency "eventmachine", ">= 1.0.0.beta.1"
25
25
  s.add_development_dependency "rspec", "~> 2.8.0"
26
- s.add_development_dependency "eventmachine", ">= 1.0.0.beta.1"
26
+ s.add_development_dependency "eventmachine", "~> 1.0.0"
27
27
  s.add_development_dependency "em-synchrony", "~> 1.0.0"
28
28
  end
@@ -1,5 +1,6 @@
1
1
  $:.unshift "lib"
2
2
  require 'em-synchrony'
3
+ require 'em-synchrony/connection_pool'
3
4
  require 'redis-em-mutex'
4
5
 
5
6
  describe Redis::EM::Mutex do
@@ -18,6 +19,67 @@ describe Redis::EM::Mutex do
18
19
  }.to raise_error(described_class::MutexError, /Can not establish watcher channel connection!/)
19
20
  end
20
21
 
22
+ it "should setup with redis connection pool" do
23
+ described_class.setup(redis: @redis_pool)
24
+ described_class.class_variable_get(:'@@redis_pool').should be @redis_pool
25
+ redis = described_class.class_variable_get(:'@@redis_watcher')
26
+ described_class.stop_watcher
27
+ redis.should be_an_instance_of Redis
28
+ redis.client.host.should eq 'localhost'
29
+ redis.client.db.should eq 1
30
+ redis.client.scheme.should eq 'redis'
31
+ end
32
+
33
+ it "should setup with various options" do
34
+ described_class.setup do |cfg|
35
+ cfg.expire = 42 # - sets global Mutex.default_expire
36
+ cfg.ns = 'redis rulez!' # - sets global Mutex.namespace
37
+ cfg.reconnect_max = -1 # - maximum num. of attempts to re-establish
38
+ cfg.url = 'redis://127.0.0.1/2'
39
+ cfg.size = 10
40
+ end
41
+ described_class.namespace.should eq 'redis rulez!'
42
+ described_class.default_expire.should eq 42
43
+ described_class.class_variable_get(:'@@connection_retry_max').should eq -1
44
+ redis_pool = described_class.class_variable_get(:'@@redis_pool')
45
+ redis_pool.should be_an_instance_of EM::Synchrony::ConnectionPool
46
+ redis_pool.should_not be @redis_pool
47
+ redis_pool.client.host.should eq '127.0.0.1'
48
+ redis_pool.client.db.should eq 2
49
+ redis_pool.client.port.should eq 6379
50
+ redis_pool.client.scheme.should eq 'redis'
51
+ redis = described_class.class_variable_get(:'@@redis_watcher')
52
+ described_class.stop_watcher
53
+ redis.should be_an_instance_of Redis
54
+ redis.client.host.should eq '127.0.0.1'
55
+ redis.client.db.should eq 2
56
+ redis.client.port.should eq 6379
57
+ redis.client.scheme.should eq 'redis'
58
+ end
59
+
60
+ it "should setup with separate redis options" do
61
+ described_class.setup do |cfg|
62
+ cfg.scheme = 'redis'
63
+ cfg.host = 'localhost'
64
+ cfg.port = 6379
65
+ cfg.db = 3
66
+ end
67
+ redis_pool = described_class.class_variable_get(:'@@redis_pool')
68
+ redis_pool.should be_an_instance_of EM::Synchrony::ConnectionPool
69
+ redis_pool.should_not be @redis_pool
70
+ redis_pool.client.host.should eq 'localhost'
71
+ redis_pool.client.db.should eq 3
72
+ redis_pool.client.port.should eq 6379
73
+ redis_pool.client.scheme.should eq 'redis'
74
+ redis = described_class.class_variable_get(:'@@redis_watcher')
75
+ redis.should be_an_instance_of Redis
76
+ described_class.stop_watcher
77
+ redis.client.host.should eq 'localhost'
78
+ redis.client.db.should eq 3
79
+ redis.client.port.should eq 6379
80
+ redis.client.scheme.should eq 'redis'
81
+ end
82
+
21
83
  around(:each) do |testcase|
22
84
  @after_em_stop = nil
23
85
  ::EM.synchrony do
@@ -30,4 +92,7 @@ describe Redis::EM::Mutex do
30
92
  @after_em_stop.call if @after_em_stop
31
93
  end
32
94
 
95
+ before(:all) do
96
+ @redis_pool = EM::Synchrony::ConnectionPool.new(size: 10) { Redis.new url: 'redis://localhost/1' }
97
+ end
33
98
  end
@@ -0,0 +1,232 @@
1
+ $:.unshift "lib"
2
+ require 'securerandom'
3
+ require 'em-synchrony'
4
+ require 'em-synchrony/fiber_iterator'
5
+ require 'redis-em-mutex'
6
+
7
+ class Test
8
+ include Redis::EM::Mutex::Macro
9
+ auto_mutex :method5
10
+ def method1; end
11
+ auto_mutex
12
+ def method2; end
13
+ no_auto_mutex
14
+ def method3; end
15
+ def method4; end
16
+ def method5; end
17
+ auto_mutex :method4
18
+ def method6; end
19
+ auto_mutex :method6, :method7, block: 10, on_timeout: proc { }
20
+ def method7; end
21
+
22
+ auto_mutex block: 20
23
+
24
+ auto_mutex
25
+ def test(redis, key, value)
26
+ redis.set key, value
27
+ ::EM::Synchrony.sleep 0.1
28
+ redis.get key
29
+ end
30
+
31
+ def recursive(n=1, &blk)
32
+ if n < 10
33
+ recursive(n+1, &blk)
34
+ else
35
+ yield n
36
+ end
37
+ end
38
+
39
+ no_auto_mutex
40
+ def test_no_mutex(redis, key, value)
41
+ redis.set key, value
42
+ ::EM::Synchrony.sleep 0.1
43
+ redis.get key
44
+ end
45
+
46
+ auto_mutex :may_timeout, block: 0, on_timeout: proc { false }
47
+ def may_timeout; yield; end
48
+
49
+ auto_mutex :may_timeout_no_fallback, block: 0
50
+ def may_timeout_no_fallback; yield; end
51
+
52
+ auto_mutex :may_timeout_method_fallback, block: 0, on_timeout: :may_timeout_timed_out
53
+ def may_timeout_method_fallback; yield; end
54
+ def may_timeout_timed_out; false; end
55
+
56
+ end
57
+
58
+ describe Redis::EM::Mutex::Macro do
59
+
60
+ it "should define auto_mutex methods" do
61
+ Test.auto_mutex_methods.keys.should eq [:method5, :method4, :method6, :method7, :may_timeout,
62
+ :may_timeout_no_fallback, :may_timeout_method_fallback]
63
+ [:method5, :method2, :method4, :test, :recursive,
64
+ :may_timeout_no_fallback, :may_timeout_method_fallback].each do |name|
65
+ Test.method_defined?(name).should be_true
66
+ Test.method_defined?("#{name}_without_auto_mutex").should be_true
67
+ Test.method_defined?("#{name}_with_auto_mutex").should be_true
68
+ Test.method_defined?("#{name}_on_timeout_auto_mutex").should be_false
69
+ end
70
+ [:method6, :method7, :may_timeout].each do |name|
71
+ Test.method_defined?(name).should be_true
72
+ Test.method_defined?("#{name}_without_auto_mutex").should be_true
73
+ Test.method_defined?("#{name}_with_auto_mutex").should be_true
74
+ Test.method_defined?("#{name}_on_timeout_auto_mutex").should be_true
75
+ end
76
+ [:method1, :method3, :test_no_mutex, :may_timeout_timed_out].each do |name|
77
+ Test.method_defined?(name).should be_true
78
+ Test.method_defined?("#{name}_without_auto_mutex").should be_false
79
+ Test.method_defined?("#{name}_with_auto_mutex").should be_false
80
+ Test.method_defined?("#{name}_on_timeout_auto_mutex").should be_false
81
+ end
82
+ end
83
+
84
+ it "should method run unprotected" do
85
+ iterate = 10.times.map { Test.new }
86
+ test_key = @test_key
87
+ results = {}
88
+ ::EM::Synchrony::FiberIterator.new(iterate, iterate.length).each do |test|
89
+ begin
90
+ redis = Redis.new @redis_options
91
+ value = test.__id__.to_s
92
+ results[value] = test.test_no_mutex(redis, test_key, value)
93
+ rescue Exception => e
94
+ @exception = e
95
+ end
96
+ end
97
+ results.length.should eq iterate.length
98
+ results.each_pair do |k, v|
99
+ v.should eq results.values.last
100
+ end
101
+ end
102
+
103
+ it "should protect auto_mutex method" do
104
+ iterate = 10.times.map { Test.new }
105
+ test_key = @test_key
106
+ results = {}
107
+ ::EM::Synchrony::FiberIterator.new(iterate, iterate.length).each do |test|
108
+ begin
109
+ redis = Redis.new @redis_options
110
+ value = test.__id__.to_s
111
+ results[value] = test.test(redis, test_key, value)
112
+ rescue Exception => e
113
+ @exception = e
114
+ end
115
+ end
116
+ results.length.should eq iterate.length
117
+ results.each_pair do |k, v|
118
+ k.should eq v
119
+ end
120
+ end
121
+
122
+ it "should allow recursive calls to protected methods" do
123
+ iterate = 10.times.map { Test.new }
124
+ test_key = @test_key
125
+ results = {}
126
+ ::EM::Synchrony::FiberIterator.new(iterate, iterate.length).each do |test|
127
+ begin
128
+ redis = Redis.new @redis_options
129
+ value = test.__id__.to_s
130
+ results[value] = test.recursive do |n|
131
+ redis.set test_key, value
132
+ ::EM::Synchrony.sleep 0.1
133
+ [redis.get(test_key), n]
134
+ end
135
+ rescue Exception => e
136
+ @exception = e
137
+ end
138
+ end
139
+ results.length.should eq iterate.length
140
+ results.each_pair do |k, v|
141
+ v.should eq [k, 10]
142
+ end
143
+ end
144
+
145
+ it "should call on_timout lambda when locking times out" do
146
+ ::EM::Synchrony.next_tick do
147
+ begin
148
+ Test.new.may_timeout do
149
+ ::EM::Synchrony.sleep 0.2
150
+ true
151
+ end.should be_true
152
+ rescue Exception => e
153
+ @exception = e
154
+ end
155
+ end
156
+ ::EM::Synchrony.sleep 0.1
157
+ Test.new.may_timeout do
158
+ true
159
+ end.should be_false
160
+ ::EM::Synchrony.sleep 0.15
161
+ end
162
+
163
+ it "should raise MutexTimeout when locking times out" do
164
+ ::EM::Synchrony.next_tick do
165
+ begin
166
+ Test.new.may_timeout_no_fallback do
167
+ ::EM::Synchrony.sleep 0.2
168
+ true
169
+ end.should be_true
170
+ rescue Exception => e
171
+ @exception = e
172
+ end
173
+ end
174
+ ::EM::Synchrony.sleep 0.1
175
+ expect {
176
+ Test.new.may_timeout_no_fallback do
177
+ true
178
+ end
179
+ }.to raise_error(Redis::EM::Mutex::MutexTimeout)
180
+ ::EM::Synchrony.sleep 0.15
181
+ end
182
+
183
+ it "should call on_timout method when locking times out" do
184
+ ::EM::Synchrony.next_tick do
185
+ begin
186
+ Test.new.may_timeout_method_fallback do
187
+ ::EM::Synchrony.sleep 0.2
188
+ true
189
+ end.should be_true
190
+ rescue Exception => e
191
+ @exception = e
192
+ end
193
+ end
194
+ ::EM::Synchrony.sleep 0.1
195
+ Test.new.may_timeout_method_fallback do
196
+ true
197
+ end.should be_false
198
+ ::EM::Synchrony.sleep 0.15
199
+ end
200
+
201
+ around(:each) do |testcase|
202
+ @after_em_stop = nil
203
+ @exception = nil
204
+ ::EM.synchrony do
205
+ begin
206
+ testcase.call
207
+ raise @exception if @exception
208
+ Redis::EM::Mutex.stop_watcher(false)
209
+ rescue => e
210
+ Redis::EM::Mutex.stop_watcher(true)
211
+ raise e
212
+ ensure
213
+ ::EM.stop
214
+ end
215
+ end
216
+ @after_em_stop.call if @after_em_stop
217
+ end
218
+
219
+ before(:all) do
220
+ @redis_options = {:driver => :synchrony}
221
+ @test_key = SecureRandom.base64(24)
222
+ Redis::EM::Mutex.setup @redis_options.merge(size: 11, ns: SecureRandom.base64(15))
223
+ end
224
+
225
+ after(:all) do
226
+ ::EM.synchrony do
227
+ Redis.new(@redis_options).del @test_key
228
+ EM.stop
229
+ end
230
+ # @lock_names
231
+ end
232
+ end
@@ -100,7 +100,7 @@ describe Redis::EM::Mutex do
100
100
  end
101
101
 
102
102
  before(:all) do
103
- @redis_options = {}
103
+ @redis_options = {:driver => :synchrony}
104
104
  described_class.setup @redis_options.merge(size: 11)
105
105
  @lock_names = 10.times.map {
106
106
  SecureRandom.random_bytes
@@ -323,7 +323,7 @@ describe Redis::EM::Mutex do
323
323
  begin
324
324
  testcase.call
325
325
  raise @exception if @exception
326
- described_class.stop_watcher(false)
326
+ described_class.stop_watcher
327
327
  rescue => e
328
328
  described_class.stop_watcher(true)
329
329
  raise e
@@ -335,7 +335,7 @@ describe Redis::EM::Mutex do
335
335
  end
336
336
 
337
337
  before(:all) do
338
- @redis_options = {}
338
+ @redis_options = {:driver => :synchrony}
339
339
  described_class.setup @redis_options.merge(size: 11)
340
340
  @lock_names = 10.times.map {
341
341
  SecureRandom.random_bytes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-em-mutex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-12 00:00:00.000000000 Z
12
+ date: 2012-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &254270740 !ruby/object:Gem::Requirement
16
+ requirement: &90657860 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 3.0.0
21
+ version: 3.0.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *254270740
24
+ version_requirements: *90657860
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: hiredis
27
- requirement: &254270280 !ruby/object:Gem::Requirement
27
+ requirement: &90657060 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,21 +32,21 @@ dependencies:
32
32
  version: 0.4.5
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *254270280
35
+ version_requirements: *90657060
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: eventmachine
38
- requirement: &254269820 !ruby/object:Gem::Requirement
38
+ requirement: &90656280 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
- version: 0.12.10
43
+ version: 1.0.0.beta.1
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *254269820
46
+ version_requirements: *90656280
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &254269360 !ruby/object:Gem::Requirement
49
+ requirement: &90655560 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,21 +54,21 @@ dependencies:
54
54
  version: 2.8.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *254269360
57
+ version_requirements: *90655560
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: eventmachine
60
- requirement: &254268900 !ruby/object:Gem::Requirement
60
+ requirement: &90654360 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
- - - ! '>='
63
+ - - ~>
64
64
  - !ruby/object:Gem::Version
65
- version: 1.0.0.beta.1
65
+ version: 1.0.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *254268900
68
+ version_requirements: *90654360
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: em-synchrony
71
- requirement: &254268440 !ruby/object:Gem::Requirement
71
+ requirement: &90652800 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: 1.0.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *254268440
79
+ version_requirements: *90652800
80
80
  description: Cross server-process-fiber EventMachine + Redis based semaphore with
81
81
  many features
82
82
  email: rafal@yeondir.com
@@ -90,8 +90,11 @@ files:
90
90
  - Rakefile
91
91
  - lib/redis-em-mutex.rb
92
92
  - lib/redis/em-mutex.rb
93
+ - lib/redis/em-mutex/macro.rb
94
+ - lib/redis/em-mutex/version.rb
93
95
  - redis-em-mutex.gemspec
94
96
  - spec/redis-em-mutex-features.rb
97
+ - spec/redis-em-mutex-macros.rb
95
98
  - spec/redis-em-mutex-namespaces.rb
96
99
  - spec/redis-em-mutex-semaphores.rb
97
100
  homepage: http://github.com/royaltm/redis-em-mutex
@@ -117,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
120
  - !ruby/object:Gem::Version
118
121
  version: '0'
119
122
  requirements:
120
- - Redis server
123
+ - Redis server 2.4+
121
124
  rubyforge_project:
122
125
  rubygems_version: 1.8.17
123
126
  signing_key:
@@ -127,3 +130,4 @@ test_files:
127
130
  - spec/redis-em-mutex-namespaces.rb
128
131
  - spec/redis-em-mutex-semaphores.rb
129
132
  - spec/redis-em-mutex-features.rb
133
+ - spec/redis-em-mutex-macros.rb