redis-em-mutex 0.1.0 → 0.1.1
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 +10 -0
- data/README.rdoc +2 -2
- data/lib/redis/em-mutex.rb +549 -555
- data/lib/redis-em-mutex.rb +5 -5
- data/spec/redis-em-mutex-namespaces.rb +113 -0
- data/spec/redis-em-mutex-semaphores.rb +184 -173
- metadata +16 -13
data/lib/redis-em-mutex.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
class Redis
|
2
|
-
module EM
|
3
|
-
autoload :Mutex, 'redis/em-mutex'
|
4
|
-
end
|
5
|
-
end
|
1
|
+
class Redis
|
2
|
+
module EM
|
3
|
+
autoload :Mutex, 'redis/em-mutex'
|
4
|
+
end
|
5
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
$:.unshift "lib"
|
2
|
+
require 'securerandom'
|
3
|
+
require 'em-synchrony'
|
4
|
+
require 'redis-em-mutex'
|
5
|
+
|
6
|
+
describe Redis::EM::Mutex do
|
7
|
+
|
8
|
+
it "should have namespaced semaphores" do
|
9
|
+
described_class.ns = 'MutexTEST'
|
10
|
+
described_class.ns.should eq 'MutexTEST'
|
11
|
+
mutex = described_class.new(*@lock_names)
|
12
|
+
mutex.instance_variable_get(:'@ns_names').each_with_index.all? do |ns_name, index|
|
13
|
+
ns_name.should eq "MutexTEST:#{@lock_names[index]}"
|
14
|
+
end
|
15
|
+
described_class.ns = nil
|
16
|
+
described_class.ns.should be_nil
|
17
|
+
mutex = described_class.new(*@lock_names)
|
18
|
+
mutex.instance_variable_get(:'@ns_names').each_with_index.all? do |ns_name, index|
|
19
|
+
ns_name.should eq "#{@lock_names[index]}"
|
20
|
+
end
|
21
|
+
mutex = described_class.new(*@lock_names, ns: 'MutexLocalTEST')
|
22
|
+
mutex.instance_variable_get(:'@ns_names').each_with_index.all? do |ns_name, index|
|
23
|
+
ns_name.should eq "MutexLocalTEST:#{@lock_names[index]}"
|
24
|
+
end
|
25
|
+
ns = described_class::NS.new(:MutexCustomTEST)
|
26
|
+
mutex = ns.new(*@lock_names)
|
27
|
+
mutex.instance_variable_get(:'@ns_names').each_with_index.all? do |ns_name, index|
|
28
|
+
ns_name.should eq "MutexCustomTEST:#{@lock_names[index]}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should lock and allow locking on the same semaphore name with different namespace" do
|
33
|
+
begin
|
34
|
+
mutex = described_class.lock(*@lock_names)
|
35
|
+
mutex.locked?.should be_true
|
36
|
+
mutex.owned?.should be_true
|
37
|
+
ns_mutex = described_class.lock(*@lock_names, ns: :MutexLocalTEST)
|
38
|
+
ns_mutex.locked?.should be_true
|
39
|
+
ns_mutex.owned?.should be_true
|
40
|
+
expect {
|
41
|
+
mutex.lock
|
42
|
+
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
43
|
+
expect {
|
44
|
+
ns_mutex.lock
|
45
|
+
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
46
|
+
mutex.unlock
|
47
|
+
mutex.locked?.should be_false
|
48
|
+
mutex.owned?.should be_false
|
49
|
+
ns_mutex.unlock
|
50
|
+
ns_mutex.locked?.should be_false
|
51
|
+
ns_mutex.owned?.should be_false
|
52
|
+
ensure
|
53
|
+
mutex.unlock if mutex
|
54
|
+
ns_mutex.unlock if ns_mutex
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should lock and allow locking on different semaphore name with the same namespace" do
|
59
|
+
begin
|
60
|
+
ns = described_class::NS.new(:MutexCustomTEST)
|
61
|
+
mutex1 = ns.lock(@lock_names.first)
|
62
|
+
mutex1.locked?.should be_true
|
63
|
+
mutex1.owned?.should be_true
|
64
|
+
mutex2 = ns.lock(@lock_names.last)
|
65
|
+
mutex2.locked?.should be_true
|
66
|
+
mutex2.owned?.should be_true
|
67
|
+
expect {
|
68
|
+
mutex1.lock
|
69
|
+
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
70
|
+
expect {
|
71
|
+
mutex2.lock
|
72
|
+
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
73
|
+
mutex1.unlock
|
74
|
+
mutex1.locked?.should be_false
|
75
|
+
mutex1.owned?.should be_false
|
76
|
+
mutex2.unlock
|
77
|
+
mutex2.locked?.should be_false
|
78
|
+
mutex2.owned?.should be_false
|
79
|
+
ensure
|
80
|
+
mutex1.unlock if mutex1
|
81
|
+
mutex2.unlock if mutex2
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
around(:each) do |testcase|
|
87
|
+
@after_em_stop = nil
|
88
|
+
::EM.synchrony do
|
89
|
+
begin
|
90
|
+
testcase.call
|
91
|
+
described_class.stop_watcher
|
92
|
+
rescue => e
|
93
|
+
described_class.stop_watcher(true)
|
94
|
+
raise e
|
95
|
+
ensure
|
96
|
+
::EM.stop
|
97
|
+
end
|
98
|
+
end
|
99
|
+
@after_em_stop.call if @after_em_stop
|
100
|
+
end
|
101
|
+
|
102
|
+
before(:all) do
|
103
|
+
@redis_options = {}
|
104
|
+
described_class.setup @redis_options.merge(size: 11)
|
105
|
+
@lock_names = 10.times.map {
|
106
|
+
SecureRandom.random_bytes
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
after(:all) do
|
111
|
+
# @lock_names
|
112
|
+
end
|
113
|
+
end
|
@@ -7,170 +7,168 @@ require 'redis-em-mutex'
|
|
7
7
|
describe Redis::EM::Mutex do
|
8
8
|
|
9
9
|
it "should lock and prevent locking on the same semaphore" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
ensure
|
26
|
-
mutex.unlock if mutex
|
27
|
-
end
|
10
|
+
described_class.new(@lock_names.first).owned?.should be_false
|
11
|
+
mutex = described_class.lock(@lock_names.first)
|
12
|
+
mutex.names.should eq [@lock_names.first]
|
13
|
+
mutex.locked?.should be_true
|
14
|
+
mutex.owned?.should be_true
|
15
|
+
mutex.should be_an_instance_of described_class
|
16
|
+
described_class.new(@lock_names.first).try_lock.should be_false
|
17
|
+
expect {
|
18
|
+
mutex.lock
|
19
|
+
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
20
|
+
mutex.unlock.should be_an_instance_of described_class
|
21
|
+
mutex.locked?.should be_false
|
22
|
+
mutex.owned?.should be_false
|
23
|
+
mutex.try_lock.should be_true
|
24
|
+
mutex.unlock if mutex
|
28
25
|
end
|
29
26
|
|
30
27
|
it "should lock and prevent locking on the same multiple semaphores" do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
mutex = described_class.lock(*@lock_names)
|
29
|
+
mutex.names.should eq @lock_names
|
30
|
+
mutex.locked?.should be_true
|
31
|
+
mutex.owned?.should be_true
|
32
|
+
mutex.should be_an_instance_of described_class
|
33
|
+
described_class.new(*@lock_names).try_lock.should be_false
|
34
|
+
@lock_names.each do |name|
|
35
|
+
described_class.new(name).try_lock.should be_false
|
36
|
+
end
|
37
|
+
mutex.try_lock.should be_false
|
38
|
+
expect {
|
39
|
+
mutex.lock
|
40
|
+
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
41
|
+
@lock_names.each do |name|
|
42
42
|
expect {
|
43
|
-
|
43
|
+
described_class.new(name).lock
|
44
44
|
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
45
|
-
@lock_names.each do |name|
|
46
|
-
expect {
|
47
|
-
described_class.new(name).lock
|
48
|
-
}.to raise_error(Redis::EM::Mutex::MutexError, /deadlock; recursive locking/)
|
49
|
-
end
|
50
|
-
mutex.unlock.should be_an_instance_of described_class
|
51
|
-
mutex.locked?.should be_false
|
52
|
-
mutex.owned?.should be_false
|
53
|
-
mutex.try_lock.should be_true
|
54
|
-
ensure
|
55
|
-
mutex.unlock if mutex
|
56
45
|
end
|
46
|
+
mutex.unlock.should be_an_instance_of described_class
|
47
|
+
mutex.locked?.should be_false
|
48
|
+
mutex.owned?.should be_false
|
49
|
+
mutex.try_lock.should be_true
|
50
|
+
mutex.unlock if mutex
|
57
51
|
end
|
58
52
|
|
59
53
|
it "should lock and prevent other fibers to lock on the same semaphore" do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
mutex.try_lock.should
|
54
|
+
mutex = described_class.lock(@lock_names.first)
|
55
|
+
mutex.should be_an_instance_of described_class
|
56
|
+
mutex.owned?.should be_true
|
57
|
+
locked = true
|
58
|
+
::EM::Synchrony.next_tick do
|
59
|
+
begin
|
60
|
+
mutex.try_lock.should be_false
|
67
61
|
mutex.owned?.should be_false
|
68
62
|
start = Time.now
|
69
63
|
mutex.synchronize do
|
70
|
-
(Time.now - start).should be_within(0.
|
71
|
-
locked.should
|
64
|
+
(Time.now - start).should be_within(0.015).of(0.26)
|
65
|
+
locked.should be_false
|
72
66
|
locked = nil
|
73
67
|
end
|
68
|
+
rescue Exception => e
|
69
|
+
@exception = e
|
74
70
|
end
|
75
|
-
::EM::Synchrony.sleep 0.25
|
76
|
-
locked = false
|
77
|
-
mutex.owned?.should be_true
|
78
|
-
mutex.unlock.should be_an_instance_of described_class
|
79
|
-
mutex.owned?.should be_false
|
80
|
-
::EM::Synchrony.sleep 0.1
|
81
|
-
locked.should be_nil
|
82
|
-
ensure
|
83
|
-
mutex.unlock if mutex
|
84
71
|
end
|
72
|
+
::EM::Synchrony.sleep 0.25
|
73
|
+
locked = false
|
74
|
+
mutex.owned?.should be_true
|
75
|
+
mutex.unlock.should be_an_instance_of described_class
|
76
|
+
mutex.owned?.should be_false
|
77
|
+
::EM::Synchrony.sleep 0.2
|
78
|
+
locked.should be_nil
|
85
79
|
end
|
86
80
|
|
87
81
|
it "should lock and prevent other fibers to lock on the same multiple semaphores" do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
locked.should
|
95
|
-
mutex.try_lock.should
|
82
|
+
mutex = described_class.lock(*@lock_names)
|
83
|
+
mutex.should be_an_instance_of described_class
|
84
|
+
mutex.owned?.should be_true
|
85
|
+
locked = true
|
86
|
+
::EM::Synchrony.next_tick do
|
87
|
+
begin
|
88
|
+
locked.should be_true
|
89
|
+
mutex.try_lock.should be_false
|
96
90
|
mutex.owned?.should be_false
|
97
91
|
start = Time.now
|
98
92
|
mutex.synchronize do
|
99
93
|
mutex.owned?.should be_true
|
100
|
-
(Time.now - start).should be_within(0.
|
101
|
-
locked.should
|
94
|
+
(Time.now - start).should be_within(0.015).of(0.26)
|
95
|
+
locked.should be_false
|
102
96
|
end
|
103
97
|
mutex.owned?.should be_false
|
104
98
|
::EM::Synchrony.sleep 0.1
|
105
99
|
start = Time.now
|
106
100
|
::EM::Synchrony::FiberIterator.new(@lock_names, @lock_names.length).each do |name|
|
107
|
-
|
108
|
-
|
109
|
-
(
|
110
|
-
|
111
|
-
|
101
|
+
begin
|
102
|
+
locked.should be_true
|
103
|
+
described_class.new(name).synchronize do
|
104
|
+
(Time.now - start).should be_within(0.015).of(0.26)
|
105
|
+
locked.should be_an_instance_of Fixnum
|
106
|
+
locked-= 1
|
107
|
+
end
|
108
|
+
rescue Exception => e
|
109
|
+
@exception = e
|
112
110
|
end
|
113
111
|
end
|
112
|
+
rescue Exception => e
|
113
|
+
@exception = e
|
114
114
|
end
|
115
|
-
::EM::Synchrony.sleep 0.25
|
116
|
-
locked = false
|
117
|
-
mutex.owned?.should be_true
|
118
|
-
mutex.unlock.should be_an_instance_of described_class
|
119
|
-
mutex.owned?.should be_false
|
120
|
-
::EM::Synchrony.sleep 0.1
|
121
|
-
|
122
|
-
locked = true
|
123
|
-
mutex.lock.should be true
|
124
|
-
::EM::Synchrony.sleep 0.25
|
125
|
-
locked = 10
|
126
|
-
mutex.unlock.should be_an_instance_of described_class
|
127
|
-
::EM::Synchrony.sleep 0.1
|
128
|
-
locked.should eq 0
|
129
|
-
ensure
|
130
|
-
mutex.unlock if mutex
|
131
115
|
end
|
116
|
+
::EM::Synchrony.sleep 0.25
|
117
|
+
locked = false
|
118
|
+
mutex.owned?.should be_true
|
119
|
+
mutex.unlock.should be_an_instance_of described_class
|
120
|
+
mutex.owned?.should be_false
|
121
|
+
::EM::Synchrony.sleep 0.1
|
122
|
+
|
123
|
+
locked = true
|
124
|
+
mutex.lock.should be_true
|
125
|
+
::EM::Synchrony.sleep 0.25
|
126
|
+
locked = 10
|
127
|
+
mutex.unlock.should be_an_instance_of described_class
|
128
|
+
::EM::Synchrony.sleep 0.1
|
129
|
+
locked.should eq 0
|
132
130
|
end
|
133
131
|
|
134
132
|
it "should lock and prevent other fibers to lock on the same semaphore with block timeout" do
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
133
|
+
mutex = described_class.lock(*@lock_names)
|
134
|
+
mutex.should be_an_instance_of described_class
|
135
|
+
mutex.owned?.should be_true
|
136
|
+
locked = true
|
137
|
+
::EM::Synchrony.next_tick do
|
138
|
+
begin
|
141
139
|
start = Time.now
|
142
|
-
mutex.lock(0.25).should
|
140
|
+
mutex.lock(0.25).should be_false
|
143
141
|
mutex.owned?.should be_false
|
144
142
|
(Time.now - start).should be_within(0.01).of(0.26)
|
145
|
-
locked.should
|
143
|
+
locked.should be_true
|
146
144
|
locked = nil
|
145
|
+
rescue Exception => e
|
146
|
+
@exception = e
|
147
147
|
end
|
148
|
-
::EM::Synchrony.sleep 0.26
|
149
|
-
locked.should be_nil
|
150
|
-
locked = false
|
151
|
-
mutex.locked?.should be_true
|
152
|
-
mutex.owned?.should be_true
|
153
|
-
mutex.unlock.should be_an_instance_of described_class
|
154
|
-
mutex.locked?.should be_false
|
155
|
-
mutex.owned?.should be_false
|
156
|
-
ensure
|
157
|
-
mutex.unlock if mutex
|
158
148
|
end
|
149
|
+
::EM::Synchrony.sleep 0.26
|
150
|
+
locked.should be_nil
|
151
|
+
locked = false
|
152
|
+
mutex.locked?.should be_true
|
153
|
+
mutex.owned?.should be_true
|
154
|
+
mutex.unlock.should be_an_instance_of described_class
|
155
|
+
mutex.locked?.should be_false
|
156
|
+
mutex.owned?.should be_false
|
159
157
|
end
|
160
158
|
|
161
159
|
it "should lock and expire while other fiber lock on the same semaphore with block timeout" do
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
160
|
+
mutex = described_class.lock(*@lock_names, expire: 0.2499999)
|
161
|
+
mutex.expire_timeout.should eq 0.2499999
|
162
|
+
mutex.should be_an_instance_of described_class
|
163
|
+
mutex.owned?.should be_true
|
164
|
+
locked = true
|
165
|
+
::EM::Synchrony.next_tick do
|
166
|
+
begin
|
169
167
|
mutex.owned?.should be_false
|
170
168
|
start = Time.now
|
171
|
-
mutex.lock(0.25).should
|
169
|
+
mutex.lock(0.25).should be_true
|
172
170
|
(Time.now - start).should be_within(0.011).of(0.26)
|
173
|
-
locked.should
|
171
|
+
locked.should be_true
|
174
172
|
locked = nil
|
175
173
|
mutex.locked?.should be_true
|
176
174
|
mutex.owned?.should be_true
|
@@ -179,52 +177,52 @@ describe Redis::EM::Mutex do
|
|
179
177
|
mutex.unlock.should be_an_instance_of described_class
|
180
178
|
mutex.owned?.should be_false
|
181
179
|
mutex.locked?.should be_false
|
180
|
+
rescue Exception => e
|
181
|
+
@exception = e
|
182
182
|
end
|
183
|
-
::EM::Synchrony.sleep 0.26
|
184
|
-
locked.should be_nil
|
185
|
-
locked = false
|
186
|
-
mutex.locked?.should be_true
|
187
|
-
mutex.owned?.should be_false
|
188
|
-
mutex.unlock.should be_an_instance_of described_class
|
189
|
-
mutex.locked?.should be_true
|
190
|
-
mutex.owned?.should be_false
|
191
|
-
::EM::Synchrony.sleep 0.2
|
192
|
-
ensure
|
193
|
-
mutex.unlock if mutex
|
194
183
|
end
|
184
|
+
::EM::Synchrony.sleep 0.26
|
185
|
+
locked.should be_nil
|
186
|
+
locked = false
|
187
|
+
mutex.locked?.should be_true
|
188
|
+
mutex.owned?.should be_false
|
189
|
+
mutex.unlock.should be_an_instance_of described_class
|
190
|
+
mutex.locked?.should be_true
|
191
|
+
mutex.owned?.should be_false
|
192
|
+
::EM::Synchrony.sleep 0.5
|
195
193
|
end
|
196
194
|
|
197
195
|
it "should lock and prevent (with refresh) other fibers to lock on the same semaphore with block timeout" do
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
196
|
+
mutex = described_class.lock(*@lock_names, expire: 0.11)
|
197
|
+
mutex.should be_an_instance_of described_class
|
198
|
+
mutex.owned?.should be_true
|
199
|
+
locked = true
|
200
|
+
::EM::Synchrony.next_tick do
|
201
|
+
begin
|
204
202
|
start = Time.now
|
205
|
-
mutex.lock(0.3).should
|
203
|
+
mutex.lock(0.3).should be_false
|
206
204
|
mutex.owned?.should be_false
|
207
205
|
(Time.now - start).should be_within(0.01).of(0.31)
|
208
|
-
locked.should
|
206
|
+
locked.should be_true
|
209
207
|
locked = nil
|
208
|
+
rescue Exception => e
|
209
|
+
@exception = e
|
210
210
|
end
|
211
|
-
::EM::Synchrony.sleep 0.08
|
212
|
-
mutex.owned?.should be_true
|
213
|
-
mutex.refresh
|
214
|
-
::EM::Synchrony.sleep 0.08
|
215
|
-
mutex.owned?.should be_true
|
216
|
-
mutex.refresh(0.5)
|
217
|
-
::EM::Synchrony.sleep 0.15
|
218
|
-
locked.should be_nil
|
219
|
-
locked = false
|
220
|
-
mutex.locked?.should be_true
|
221
|
-
mutex.owned?.should be_true
|
222
|
-
mutex.unlock.should be_an_instance_of described_class
|
223
|
-
mutex.locked?.should be_false
|
224
|
-
mutex.owned?.should be_false
|
225
|
-
ensure
|
226
|
-
mutex.unlock if mutex
|
227
211
|
end
|
212
|
+
::EM::Synchrony.sleep 0.08
|
213
|
+
mutex.owned?.should be_true
|
214
|
+
mutex.refresh
|
215
|
+
::EM::Synchrony.sleep 0.08
|
216
|
+
mutex.owned?.should be_true
|
217
|
+
mutex.refresh(0.5)
|
218
|
+
::EM::Synchrony.sleep 0.15
|
219
|
+
locked.should be_nil
|
220
|
+
locked = false
|
221
|
+
mutex.locked?.should be_true
|
222
|
+
mutex.owned?.should be_true
|
223
|
+
mutex.unlock.should be_an_instance_of described_class
|
224
|
+
mutex.locked?.should be_false
|
225
|
+
mutex.owned?.should be_false
|
228
226
|
end
|
229
227
|
|
230
228
|
it "should lock some resource and play with it safely" do
|
@@ -232,20 +230,24 @@ describe Redis::EM::Mutex do
|
|
232
230
|
play_name = SecureRandom.random_bytes
|
233
231
|
result = []
|
234
232
|
::EM::Synchrony::FiberIterator.new((0..9).to_a, 10).each do |i|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
mutex.
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
233
|
+
begin
|
234
|
+
was_locked = false
|
235
|
+
redis = Redis.new @redis_options
|
236
|
+
mutex.owned?.should be_false
|
237
|
+
mutex.synchronize do
|
238
|
+
mutex.owned?.should be_true
|
239
|
+
was_locked = true
|
240
|
+
redis.setnx(play_name, i).should be_true
|
241
|
+
::EM::Synchrony.sleep 0.1
|
242
|
+
redis.get(play_name).should eq i.to_s
|
243
|
+
redis.del(play_name).should eq 1
|
244
|
+
end
|
245
|
+
was_locked.should be_true
|
246
|
+
mutex.owned?.should be_false
|
247
|
+
result << i
|
248
|
+
rescue Exception => e
|
249
|
+
@exception = e
|
245
250
|
end
|
246
|
-
was_locked.should be_true
|
247
|
-
mutex.owned?.should be_false
|
248
|
-
result << i
|
249
251
|
end
|
250
252
|
mutex.locked?.should be_false
|
251
253
|
result.sort.should eq (0..9).to_a
|
@@ -256,14 +258,18 @@ describe Redis::EM::Mutex do
|
|
256
258
|
mutex.should be_an_instance_of described_class
|
257
259
|
time = nil
|
258
260
|
EM::Synchrony.next_tick do
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
261
|
+
begin
|
262
|
+
time.should be_nil
|
263
|
+
was_locked = false
|
264
|
+
mutex.synchronize do
|
265
|
+
time.should be_an_instance_of Time
|
266
|
+
(Time.now - time).should be < 0.0009
|
267
|
+
was_locked = true
|
268
|
+
end
|
269
|
+
was_locked.should be_true
|
270
|
+
rescue Exception => e
|
271
|
+
@exception = e
|
265
272
|
end
|
266
|
-
was_locked.should be_true
|
267
273
|
end
|
268
274
|
EM::Synchrony.sleep 0.1
|
269
275
|
mutex.owned?.should be_true
|
@@ -312,11 +318,16 @@ describe Redis::EM::Mutex do
|
|
312
318
|
|
313
319
|
around(:each) do |testcase|
|
314
320
|
@after_em_stop = nil
|
321
|
+
@exception = nil
|
315
322
|
::EM.synchrony do
|
316
323
|
begin
|
317
324
|
testcase.call
|
318
|
-
|
325
|
+
raise @exception if @exception
|
319
326
|
described_class.stop_watcher(false)
|
327
|
+
rescue => e
|
328
|
+
described_class.stop_watcher(true)
|
329
|
+
raise e
|
330
|
+
ensure
|
320
331
|
::EM.stop
|
321
332
|
end
|
322
333
|
end
|
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.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-09-12 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &254270740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *254270740
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: hiredis
|
27
|
-
requirement: &
|
27
|
+
requirement: &254270280 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.4.5
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *254270280
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: eventmachine
|
38
|
-
requirement: &
|
38
|
+
requirement: &254269820 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.12.10
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *254269820
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &254269360 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 2.8.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *254269360
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: eventmachine
|
60
|
-
requirement: &
|
60
|
+
requirement: &254268900 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.0.0.beta.1
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *254268900
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: em-synchrony
|
71
|
-
requirement: &
|
71
|
+
requirement: &254268440 !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: *
|
79
|
+
version_requirements: *254268440
|
80
80
|
description: Cross server-process-fiber EventMachine + Redis based semaphore with
|
81
81
|
many features
|
82
82
|
email: rafal@yeondir.com
|
@@ -85,12 +85,14 @@ extensions: []
|
|
85
85
|
extra_rdoc_files:
|
86
86
|
- README.rdoc
|
87
87
|
files:
|
88
|
+
- HISTORY.rdoc
|
88
89
|
- README.rdoc
|
89
90
|
- Rakefile
|
90
91
|
- lib/redis-em-mutex.rb
|
91
92
|
- lib/redis/em-mutex.rb
|
92
93
|
- redis-em-mutex.gemspec
|
93
94
|
- spec/redis-em-mutex-features.rb
|
95
|
+
- spec/redis-em-mutex-namespaces.rb
|
94
96
|
- spec/redis-em-mutex-semaphores.rb
|
95
97
|
homepage: http://github.com/royaltm/redis-em-mutex
|
96
98
|
licenses: []
|
@@ -122,5 +124,6 @@ signing_key:
|
|
122
124
|
specification_version: 3
|
123
125
|
summary: Cross server-process-fiber EventMachine + Redis based semaphore
|
124
126
|
test_files:
|
127
|
+
- spec/redis-em-mutex-namespaces.rb
|
125
128
|
- spec/redis-em-mutex-semaphores.rb
|
126
129
|
- spec/redis-em-mutex-features.rb
|