redis-em-mutex 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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