zk 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -0
- data/Gemfile +2 -3
- data/README.markdown +7 -7
- data/RELEASES.markdown +18 -0
- data/Rakefile +6 -2
- data/lib/zk/client/conveniences.rb +47 -37
- data/lib/zk/client/threaded.rb +15 -4
- data/lib/zk/client/unixisms.rb +23 -14
- data/lib/zk/client.rb +1 -0
- data/lib/zk/event_handler.rb +1 -1
- data/lib/zk/exceptions.rb +24 -21
- data/lib/zk/locker/exclusive_locker.rb +75 -0
- data/lib/zk/locker/locker_base.rb +161 -0
- data/lib/zk/locker/shared_locker.rb +101 -0
- data/lib/zk/locker.rb +109 -240
- data/lib/zk/message_queue.rb +16 -6
- data/lib/zk/pool.rb +5 -4
- data/lib/zk/version.rb +1 -1
- data/spec/zk/locker_spec.rb +46 -102
- data/spec/zk/pool_spec.rb +1 -1
- metadata +7 -4
data/lib/zk/version.rb
CHANGED
data/spec/zk/locker_spec.rb
CHANGED
@@ -76,44 +76,6 @@ describe 'ZK::Client#locker' do
|
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
-
# describe 'Locker thread safety' do
|
80
|
-
# describe 'exception' do
|
81
|
-
# before do
|
82
|
-
# @path = '/zk_test'
|
83
|
-
# @zk = ZK.new("localhost:#{ZK.test_port}")
|
84
|
-
# @zk.create(@path) rescue ZK::Exceptions::NodeExists
|
85
|
-
# end
|
86
|
-
|
87
|
-
# after do
|
88
|
-
# @zk.rm_rf(@path)
|
89
|
-
# @zk.close!
|
90
|
-
# end
|
91
|
-
|
92
|
-
# it %[should raise an EventDispatchThreadException if called in the dispatch thread] do
|
93
|
-
# @exception = nil
|
94
|
-
|
95
|
-
# @zk.register(@path) do |event|
|
96
|
-
# @zk.event_dispatch_thread?.should be_true
|
97
|
-
|
98
|
-
# begin
|
99
|
-
# @zk.with_lock('boguslockname') do
|
100
|
-
# raise "Should never have gotten this far"
|
101
|
-
# end
|
102
|
-
# rescue Exception => e
|
103
|
-
# @exception = e
|
104
|
-
# end
|
105
|
-
# end
|
106
|
-
|
107
|
-
# @zk.exists?(@path, :watch => true)
|
108
|
-
|
109
|
-
# @zk.set(@path, 'blah')
|
110
|
-
|
111
|
-
# wait_until(2) { @exception }.should be_kind_of(ZK::Exceptions::EventDispatchThreadException)
|
112
|
-
# end
|
113
|
-
# end
|
114
|
-
|
115
|
-
# end
|
116
|
-
|
117
79
|
shared_examples_for 'SharedLocker' do
|
118
80
|
before do
|
119
81
|
@shared_locker = ZK::Locker.shared_locker(zk, path)
|
@@ -253,98 +215,80 @@ end # ExclusiveLocker
|
|
253
215
|
|
254
216
|
shared_examples_for 'shared-exclusive interaction' do
|
255
217
|
before do
|
218
|
+
zk.rm_rf('/_zklocking')
|
256
219
|
@sh_lock = ZK::Locker.shared_locker(zk, path)
|
257
220
|
@ex_lock = ZK::Locker.exclusive_locker(zk2, path)
|
258
221
|
end
|
259
222
|
|
260
223
|
describe 'shared lock acquired first' do
|
261
224
|
it %[should block exclusive locks from acquiring until released] do
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
th1 = Thread.new do
|
266
|
-
@sh_lock.with_lock do
|
267
|
-
q1.enq(:got_lock)
|
268
|
-
Thread.current[:got_lock] = true
|
269
|
-
q2.pop
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
th2 = Thread.new do
|
274
|
-
q1.pop # wait for th1 to get the shared lock
|
275
|
-
|
276
|
-
Thread.current[:acquiring_lock] = true
|
225
|
+
@sh_lock.lock!.should be_true
|
226
|
+
@ex_lock.lock!.should be_false
|
277
227
|
|
228
|
+
mutex = Monitor.new
|
229
|
+
cond = mutex.new_cond
|
230
|
+
|
231
|
+
th = Thread.new do
|
232
|
+
logger.debug { "@ex_lock trying to acquire acquire lock" }
|
278
233
|
@ex_lock.with_lock do
|
279
|
-
|
234
|
+
th[:got_lock] = @ex_lock.locked?
|
235
|
+
logger.debug { "@ex_lock.locked? #{@ex_lock.locked?}" }
|
236
|
+
|
237
|
+
mutex.synchronize do
|
238
|
+
cond.broadcast
|
239
|
+
end
|
280
240
|
end
|
281
241
|
end
|
282
242
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
q2.enq(:release)
|
291
|
-
|
292
|
-
th1.join_until { q2.size == 0 }
|
293
|
-
q2.size.should == 0
|
243
|
+
mutex.synchronize do
|
244
|
+
logger.debug { "unlocking the shared lock" }
|
245
|
+
@sh_lock.unlock!.should be_true
|
246
|
+
cond.wait_until { th[:got_lock] } # make sure they actually received the lock (avoid race)
|
247
|
+
th[:got_lock].should be_true
|
248
|
+
logger.debug { "ok, they got the lock" }
|
249
|
+
end
|
294
250
|
|
295
|
-
|
251
|
+
th.join(5).should == th
|
296
252
|
|
297
|
-
|
298
|
-
th2[:got_lock].should be_true
|
253
|
+
logger.debug { "thread joined, exclusive lock should be releasd" }
|
299
254
|
|
300
|
-
|
255
|
+
@ex_lock.should_not be_locked
|
301
256
|
end
|
302
257
|
end
|
303
258
|
|
304
259
|
describe 'exclusive lock acquired first' do
|
305
260
|
it %[should block shared lock from acquiring until released] do
|
306
|
-
|
307
|
-
|
261
|
+
@ex_lock.lock!.should be_true
|
262
|
+
@sh_lock.lock!.should be_false
|
308
263
|
|
309
|
-
|
310
|
-
|
264
|
+
mutex = Monitor.new
|
265
|
+
cond = mutex.new_cond
|
266
|
+
|
267
|
+
th = Thread.new do
|
268
|
+
logger.debug { "@ex_lock trying to acquire acquire lock" }
|
269
|
+
@sh_lock.with_lock do
|
270
|
+
th[:got_lock] = @sh_lock.locked?
|
271
|
+
logger.debug { "@sh_lock.locked? #{@sh_lock.locked?}" }
|
311
272
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
Thread.current[:got_lock] = true
|
316
|
-
q2.pop
|
273
|
+
mutex.synchronize do
|
274
|
+
cond.broadcast
|
275
|
+
end
|
317
276
|
end
|
318
277
|
end
|
319
278
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
Thread.current[:got_lock] = true
|
327
|
-
end
|
279
|
+
mutex.synchronize do
|
280
|
+
logger.debug { "unlocking the shared lock" }
|
281
|
+
@ex_lock.unlock!.should be_true
|
282
|
+
cond.wait_until { th[:got_lock] } # make sure they actually received the lock (avoid race)
|
283
|
+
th[:got_lock].should be_true
|
284
|
+
logger.debug { "ok, they got the lock" }
|
328
285
|
end
|
329
286
|
|
330
|
-
|
331
|
-
th1[:got_lock].should be_true
|
332
|
-
|
333
|
-
th2.join_until { th2[:acquiring_lock] }
|
334
|
-
th2[:acquiring_lock].should be_true
|
335
|
-
|
336
|
-
q2.num_waiting.should > 0
|
337
|
-
q2.enq(:release)
|
338
|
-
|
339
|
-
th1.join_until { q2.size == 0 }
|
340
|
-
q2.size.should == 0
|
341
|
-
|
342
|
-
th1.join(2).should == th1
|
287
|
+
th.join(5).should == th
|
343
288
|
|
344
|
-
|
345
|
-
th2[:got_lock].should be_true
|
289
|
+
logger.debug { "thread joined, exclusive lock should be releasd" }
|
346
290
|
|
347
|
-
|
291
|
+
@sh_lock.should_not be_locked
|
348
292
|
end
|
349
293
|
end
|
350
294
|
|
data/spec/zk/pool_spec.rb
CHANGED
@@ -109,7 +109,7 @@ describe ZK::Pool do
|
|
109
109
|
|
110
110
|
@connection_pool.force_close!
|
111
111
|
|
112
|
-
lambda { th.join(
|
112
|
+
lambda { th.join(5) }.should raise_error(ZK::Exceptions::PoolIsShuttingDownException)
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 1
|
10
|
+
version: 1.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jonathan D. Simms
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-05-
|
19
|
+
date: 2012-05-04 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: slyphon-zookeeper
|
@@ -78,6 +78,9 @@ files:
|
|
78
78
|
- lib/zk/extensions.rb
|
79
79
|
- lib/zk/find.rb
|
80
80
|
- lib/zk/locker.rb
|
81
|
+
- lib/zk/locker/exclusive_locker.rb
|
82
|
+
- lib/zk/locker/locker_base.rb
|
83
|
+
- lib/zk/locker/shared_locker.rb
|
81
84
|
- lib/zk/logging.rb
|
82
85
|
- lib/zk/message_queue.rb
|
83
86
|
- lib/zk/mongoid.rb
|