zk 1.9.3 → 1.10.0

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.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/build.yml +55 -0
  3. data/.gitignore +1 -0
  4. data/Gemfile +18 -8
  5. data/README.markdown +9 -9
  6. data/RELEASES.markdown +28 -1
  7. data/lib/zk/client/base.rb +15 -0
  8. data/lib/zk/client/threaded.rb +3 -3
  9. data/lib/zk/client.rb +1 -1
  10. data/lib/zk/election.rb +1 -1
  11. data/lib/zk/event_handler.rb +16 -8
  12. data/lib/zk/event_handler_subscription/base.rb +1 -1
  13. data/lib/zk/fork_hook.rb +9 -4
  14. data/lib/zk/locker/locker_base.rb +14 -2
  15. data/lib/zk/locker/semaphore.rb +1 -3
  16. data/lib/zk/logger.rb +34 -0
  17. data/lib/zk/node_deletion_watcher.rb +4 -5
  18. data/lib/zk/pool.rb +12 -12
  19. data/lib/zk/subscription.rb +1 -1
  20. data/lib/zk/threaded_callback.rb +1 -1
  21. data/lib/zk/threadpool.rb +1 -1
  22. data/lib/zk/version.rb +1 -1
  23. data/lib/zk.rb +1 -5
  24. data/spec/event_catcher_spec.rb +1 -1
  25. data/spec/logging_progress_bar_formatter.rb +1 -1
  26. data/spec/message_queue_spec.rb +6 -6
  27. data/spec/shared/client_examples.rb +81 -81
  28. data/spec/shared/locker_examples.rb +13 -13
  29. data/spec/spec_helper.rb +12 -13
  30. data/spec/support/bogus_mongoid.rb +1 -1
  31. data/spec/support/client_forker.rb +1 -1
  32. data/spec/support/event_catcher.rb +1 -1
  33. data/spec/support/logging.rb +15 -47
  34. data/spec/zk/00_forked_client_integration_spec.rb +3 -3
  35. data/spec/zk/client/locking_and_session_death_spec.rb +2 -2
  36. data/spec/zk/client_spec.rb +19 -19
  37. data/spec/zk/election_spec.rb +44 -44
  38. data/spec/zk/extensions_spec.rb +2 -2
  39. data/spec/zk/locker/exclusive_locker_spec.rb +41 -41
  40. data/spec/zk/locker/locker_basic_spec.rb +55 -33
  41. data/spec/zk/locker/semaphore_spec.rb +39 -32
  42. data/spec/zk/locker/shared_exclusive_integration_spec.rb +37 -37
  43. data/spec/zk/locker/shared_locker_spec.rb +43 -43
  44. data/spec/zk/locker_spec.rb +2 -2
  45. data/spec/zk/module_spec.rb +25 -25
  46. data/spec/zk/mongoid_spec.rb +47 -47
  47. data/spec/zk/node_deletion_watcher_spec.rb +39 -31
  48. data/spec/zk/pool_spec.rb +56 -65
  49. data/spec/zk/threaded_callback_spec.rb +10 -10
  50. data/spec/zk/threadpool_spec.rb +25 -25
  51. data/spec/zk/watch_spec.rb +67 -79
  52. data/spec/zk/zookeeper_spec.rb +36 -30
  53. data/zk.gemspec +1 -2
  54. metadata +26 -47
  55. data/.travis.yml +0 -25
  56. data/lib/zk/logging.rb +0 -36
@@ -9,13 +9,13 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
9
9
 
10
10
  it %[should raise LockAssertionFailedError if there is an exclusive lock with a number lower than ours] do
11
11
  # this should *really* never happen
12
-
12
+
13
13
  rlp = locker.root_lock_path
14
14
 
15
15
  zk.mkdir_p(rlp)
16
16
 
17
17
  bogus_path = zk.create("#{rlp}/#{ZK::Locker::EXCLUSIVE_LOCK_PREFIX}", :sequential => true, :ephemeral => true)
18
- logger.debug { "bogus_path: #{bogus_path.inspect}" }
18
+ logger.debug { "bogus_path: #{bogus_path.inspect}" }
19
19
 
20
20
  th = Thread.new do
21
21
  locker.lock(true)
@@ -24,40 +24,40 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
24
24
  th.run
25
25
 
26
26
  logger.debug { "calling wait_until_blocked" }
27
- proc { locker.wait_until_blocked(5) }.should_not raise_error
27
+ expect { locker.wait_until_blocked(5) }.not_to raise_error
28
28
  logger.debug { "wait_until_blocked returned" }
29
- locker.should be_waiting
29
+ expect(locker).to be_waiting
30
30
 
31
31
  wait_until { zk.exists?(locker.lock_path) }
32
32
 
33
- zk.exists?(locker.lock_path).should be_true
33
+ expect(zk.exists?(locker.lock_path)).to be(true)
34
34
 
35
35
  zk.delete(bogus_path)
36
36
 
37
- th.join(5).should == th
37
+ expect(th.join(5)).to eq(th)
38
38
 
39
- locker.lock_path.should_not == bogus_path
39
+ expect(locker.lock_path).not_to eq(bogus_path)
40
40
 
41
41
  zk.create(bogus_path, :ephemeral => true)
42
42
 
43
- lambda { locker.assert! }.should raise_error(ZK::Exceptions::LockAssertionFailedError)
43
+ expect { locker.assert! }.to raise_error(ZK::Exceptions::LockAssertionFailedError)
44
44
  end
45
45
  end
46
46
 
47
47
  describe :acquirable? do
48
48
  it %[should work if the lock root doesn't exist] do
49
49
  zk.rm_rf(ZK::Locker.default_root_lock_node)
50
- locker.should be_acquirable
50
+ expect(locker).to be_acquirable
51
51
  end
52
52
 
53
53
  it %[should check local state of lockedness] do
54
- locker.lock.should be_true
55
- locker.should be_acquirable
54
+ expect(locker.lock).to be(true)
55
+ expect(locker).to be_acquirable
56
56
  end
57
57
 
58
58
  it %[should check if any participants would prevent us from acquiring the lock] do
59
- locker.lock.should be_true
60
- locker2.should_not be_acquirable
59
+ expect(locker.lock).to be(true)
60
+ expect(locker2).not_to be_acquirable
61
61
  end
62
62
  end
63
63
 
@@ -69,16 +69,16 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
69
69
  end
70
70
 
71
71
  it %[should acquire the first lock] do
72
- @rval.should be_true
72
+ expect(@rval).to be(true)
73
73
  end
74
74
 
75
75
  it %[should not acquire the second lock] do
76
- @rval2.should be_false
76
+ expect(@rval2).to be(false)
77
77
  end
78
78
 
79
79
  it %[should acquire the second lock after the first lock is released] do
80
- locker.unlock.should be_true
81
- locker2.lock.should be_true
80
+ expect(locker.unlock).to be(true)
81
+ expect(locker2.lock).to be(true)
82
82
  end
83
83
  end
84
84
 
@@ -95,7 +95,7 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
95
95
  it %[should block waiting for the lock with old style lock semantics] do
96
96
  ary = []
97
97
 
98
- locker.lock.should be_false
98
+ expect(locker.lock).to be(false)
99
99
 
100
100
  th = Thread.new do
101
101
  locker.lock(true)
@@ -103,22 +103,22 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
103
103
  end
104
104
 
105
105
  locker.wait_until_blocked(5)
106
-
107
- ary.should be_empty
108
- locker.should_not be_locked
106
+
107
+ expect(ary).to be_empty
108
+ expect(locker).not_to be_locked
109
109
 
110
110
  zk.delete(@read_lock_path)
111
111
 
112
- th.join(2).should == th
112
+ expect(th.join(2)).to eq(th)
113
113
 
114
- ary.length.should == 1
115
- locker.should be_locked
114
+ expect(ary.length).to eq(1)
115
+ expect(locker).to be_locked
116
116
  end
117
117
 
118
118
  it %[should block waiting for the lock with new style lock semantics] do
119
119
  ary = []
120
120
 
121
- locker.lock.should be_false
121
+ expect(locker.lock).to be(false)
122
122
 
123
123
  th = Thread.new do
124
124
  locker.lock(:wait => true)
@@ -126,24 +126,24 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
126
126
  end
127
127
 
128
128
  locker.wait_until_blocked(5)
129
-
130
- ary.should be_empty
131
- locker.should_not be_locked
129
+
130
+ expect(ary).to be_empty
131
+ expect(locker).not_to be_locked
132
132
 
133
133
  zk.delete(@read_lock_path)
134
134
 
135
- th.join(2).should == th
135
+ expect(th.join(2)).to eq(th)
136
136
 
137
- ary.length.should == 1
138
- locker.should be_locked
137
+ expect(ary.length).to eq(1)
138
+ expect(locker).to be_locked
139
139
  end
140
140
 
141
141
  it %[should time out waiting for the lock] do
142
142
  ary = []
143
143
 
144
- zk.children(lock_path_base).length.should == 1
144
+ expect(zk.children(lock_path_base).length).to eq(1)
145
145
 
146
- locker.lock.should be_false
146
+ expect(locker.lock).to be(false)
147
147
 
148
148
  th = Thread.new do
149
149
  begin
@@ -155,17 +155,17 @@ shared_examples_for 'ZK::Locker::ExclusiveLocker' do
155
155
  end
156
156
 
157
157
  locker.wait_until_blocked(5)
158
-
159
- ary.should be_empty
160
- locker.should_not be_locked
161
158
 
162
- th.join(2).should == th
159
+ expect(ary).to be_empty
160
+ expect(locker).not_to be_locked
161
+
162
+ expect(th.join(2)).to eq(th)
163
163
 
164
- zk.children(lock_path_base).length.should == 1
164
+ expect(zk.children(lock_path_base).length).to eq(1)
165
165
 
166
- ary.should be_empty
167
- @exc.should_not be_nil
168
- @exc.should be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
166
+ expect(ary).to be_empty
167
+ expect(@exc).not_to be_nil
168
+ expect(@exc).to be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
169
169
  end
170
170
  end # blocking
171
171
  end # lock
@@ -20,47 +20,47 @@ describe 'ZK::Client#locker' do
20
20
  @zk.close!
21
21
  @zk2.close!
22
22
  @zk3.close!
23
- wait_until { @connections.all? { |c| c.closed? } }
23
+ wait_until { @connections.all? { |c| c.closed? } }
24
24
  end
25
25
 
26
26
  it "should be able to acquire the lock if no one else is locking it" do
27
- @zk.locker(@path_to_lock).lock.should be_true
27
+ expect(@zk.locker(@path_to_lock).lock).to be(true)
28
28
  end
29
29
 
30
30
  it "should not be able to acquire the lock if someone else is locking it" do
31
- @zk.locker(@path_to_lock).lock.should be_true
32
- @zk2.locker(@path_to_lock).lock.should be_false
31
+ expect(@zk.locker(@path_to_lock).lock).to be(true)
32
+ expect(@zk2.locker(@path_to_lock).lock).to be(false)
33
33
  end
34
34
 
35
35
  it "should assert properly if lock is acquired" do
36
- @zk.locker(@path_to_lock).assert.should be_false
36
+ expect(@zk.locker(@path_to_lock).assert).to be(false)
37
37
  l = @zk2.locker(@path_to_lock)
38
- l.lock.should be_true
39
- l.assert.should be_true
38
+ expect(l.lock).to be(true)
39
+ expect(l.assert).to be(true)
40
40
  end
41
41
 
42
42
  it "should be able to acquire the lock after the first one releases it" do
43
43
  lock1 = @zk.locker(@path_to_lock)
44
44
  lock2 = @zk2.locker(@path_to_lock)
45
-
46
- lock1.lock.should be_true
47
- lock2.lock.should be_false
45
+
46
+ expect(lock1.lock).to be(true)
47
+ expect(lock2.lock).to be(false)
48
48
  lock1.unlock
49
- lock2.lock.should be_true
49
+ expect(lock2.lock).to be(true)
50
50
  end
51
51
 
52
52
  it "should be able to acquire the lock if the first locker goes away" do
53
53
  lock1 = @zk.locker(@path_to_lock)
54
54
  lock2 = @zk2.locker(@path_to_lock)
55
55
 
56
- lock1.lock.should be_true
57
- lock2.lock.should be_false
56
+ expect(lock1.lock).to be(true)
57
+ expect(lock2.lock).to be(false)
58
58
  @zk.close!
59
- lock2.lock.should be_true
59
+ expect(lock2.lock).to be(true)
60
60
  end
61
61
 
62
62
  it "should be able to handle multi part path locks" do
63
- @zk.locker("my/multi/part/path").lock.should be_true
63
+ expect(@zk.locker("my/multi/part/path").lock).to be(true)
64
64
  end
65
65
 
66
66
  describe :with_lock do
@@ -70,23 +70,23 @@ describe 'ZK::Client#locker' do
70
70
  describe 'Client::Conveniences' do
71
71
  it %[should yield the lock instance to the block] do
72
72
  @zk.with_lock(@path_to_lock) do |lock|
73
- lock.should_not be_nil
74
- lock.should be_kind_of(ZK::Locker::LockerBase)
75
- lambda { lock.assert! }.should_not raise_error
73
+ expect(lock).not_to be_nil
74
+ expect(lock).to be_kind_of(ZK::Locker::LockerBase)
75
+ expect { lock.assert! }.not_to raise_error
76
76
  end
77
77
  end
78
78
 
79
79
  it %[should yield a shared lock when :mode => shared given] do
80
80
  @zk.with_lock(@path_to_lock, :mode => :shared) do |lock|
81
- lock.should_not be_nil
82
- lock.should be_kind_of(ZK::Locker::SharedLocker)
83
- lambda { lock.assert! }.should_not raise_error
81
+ expect(lock).not_to be_nil
82
+ expect(lock).to be_kind_of(ZK::Locker::SharedLocker)
83
+ expect { lock.assert! }.not_to raise_error
84
84
  end
85
85
  end
86
86
 
87
87
  it %[should take a timeout] do
88
88
  first_lock = @zk.locker(@path_to_lock)
89
- first_lock.lock.should be_true
89
+ expect(first_lock.lock).to be(true)
90
90
 
91
91
  thread = Thread.new do
92
92
  begin
@@ -98,8 +98,8 @@ describe 'ZK::Client#locker' do
98
98
  end
99
99
  end
100
100
 
101
- thread.join(2).should == thread
102
- @exc.should be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
101
+ expect(thread.join(2)).to eq(thread)
102
+ expect(@exc).to be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
103
103
  end
104
104
  end
105
105
 
@@ -107,26 +107,26 @@ describe 'ZK::Client#locker' do
107
107
  it "should blocking lock" do
108
108
  array = []
109
109
  first_lock = @zk.locker("mylock")
110
- first_lock.lock.should be_true
110
+ expect(first_lock.lock).to be(true)
111
111
  array << :first_lock
112
112
 
113
113
  thread = Thread.new do
114
114
  @zk.locker("mylock").with_lock do
115
115
  array << :second_lock
116
116
  end
117
- array.length.should == 2
117
+ expect(array.length).to eq(2)
118
118
  end
119
119
 
120
- array.length.should == 1
120
+ expect(array.length).to eq(1)
121
121
  first_lock.unlock
122
122
  thread.join(10)
123
- array.length.should == 2
123
+ expect(array.length).to eq(2)
124
124
  end
125
125
 
126
126
  it %[should accept a :wait option] do
127
127
  array = []
128
128
  first_lock = @zk.locker("mylock")
129
- first_lock.lock.should be_true
129
+ expect(first_lock.lock).to be(true)
130
130
 
131
131
  second_lock = @zk.locker("mylock")
132
132
 
@@ -140,10 +140,32 @@ describe 'ZK::Client#locker' do
140
140
  end
141
141
  end
142
142
 
143
- array.should be_empty
144
- thread.join(2).should == thread
145
- @exc.should_not be_nil
146
- @exc.should be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
143
+ expect(array).to be_empty
144
+ expect(thread.join(2)).to eq(thread)
145
+ expect(@exc).not_to be_nil
146
+ expect(@exc).to be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
147
+ end
148
+
149
+ it "should interrupt a blocked lock" do
150
+ first_lock = @zk.locker("mylock")
151
+ expect(first_lock.lock).to be(true)
152
+
153
+ second_lock = @zk.locker("mylock")
154
+ thread = Thread.new do
155
+ begin
156
+ second_lock.with_lock do
157
+ raise "NO NO NO!! should not have called the block!!"
158
+ end
159
+ rescue Exception => e
160
+ @exc = e
161
+ end
162
+ end
163
+
164
+ Thread.pass until second_lock.waiting?
165
+
166
+ second_lock.interrupt!
167
+ thread.join(2)
168
+ expect(@exc).to be_kind_of(ZK::Exceptions::WakeUpException)
147
169
  end
148
170
  end
149
171
  end # with_lock
@@ -10,25 +10,32 @@ shared_examples_for 'ZK::Locker::Semaphore' do
10
10
  it_should_behave_like 'LockerBase#assert!'
11
11
  end
12
12
 
13
+ context %[invalid semaphore_size] do
14
+ let(:semaphore_size) { :boom }
15
+ it 'should raise' do
16
+ expect{ locker }.to raise_error(ZK::Exceptions::BadArguments)
17
+ end
18
+ end
19
+
13
20
  describe :acquirable? do
14
21
  describe %[with default options] do
15
22
  it %[should work if the lock root doesn't exist] do
16
23
  zk.rm_rf(ZK::Locker::Semaphore.default_root_node)
17
- locker.should be_acquirable
24
+ expect(locker).to be_acquirable
18
25
  end
19
26
 
20
27
  it %[should check local state of lockedness] do
21
- locker.lock.should be_true
22
- locker.should be_acquirable
28
+ expect(locker.lock).to be(true)
29
+ expect(locker).to be_acquirable
23
30
  end
24
31
 
25
32
  it %[should check if any participants would prevent us from acquiring the lock] do
26
- locker3.lock.should be_true
27
- locker.should be_acquirable # total locks given less than semaphore_size
28
- locker2.lock.should be_true
29
- locker.should_not be_acquirable # total locks given equal to semaphore size
33
+ expect(locker3.lock).to be(true)
34
+ expect(locker).to be_acquirable # total locks given less than semaphore_size
35
+ expect(locker2.lock).to be(true)
36
+ expect(locker).not_to be_acquirable # total locks given equal to semaphore size
30
37
  locker3.unlock
31
- locker.should be_acquirable # total locks given less than semaphore_size
38
+ expect(locker).to be_acquirable # total locks given less than semaphore_size
32
39
  end
33
40
  end
34
41
  end
@@ -41,13 +48,13 @@ shared_examples_for 'ZK::Locker::Semaphore' do
41
48
  end
42
49
 
43
50
  it %[should acquire the first lock] do
44
- @rval.should be_true
45
- locker.should be_locked
51
+ expect(@rval).to be(true)
52
+ expect(locker).to be_locked
46
53
  end
47
54
 
48
55
  it %[should acquire the second lock] do
49
- @rval2.should be_true
50
- locker2.should be_locked
56
+ expect(@rval2).to be(true)
57
+ expect(locker2).to be_locked
51
58
  end
52
59
  end
53
60
 
@@ -61,15 +68,15 @@ shared_examples_for 'ZK::Locker::Semaphore' do
61
68
  end
62
69
 
63
70
  it %[should return false] do
64
- @rval.should be_false
71
+ expect(@rval).to be(false)
65
72
  end
66
73
 
67
74
  it %[should not be locked] do
68
- locker.should_not be_locked
75
+ expect(locker).not_to be_locked
69
76
  end
70
77
 
71
78
  it %[should not have a lock_path] do
72
- locker.lock_path.should be_nil
79
+ expect(locker.lock_path).to be_nil
73
80
  end
74
81
  end
75
82
 
@@ -87,7 +94,7 @@ shared_examples_for 'ZK::Locker::Semaphore' do
87
94
  it %[should acquire the lock after the write lock is released] do
88
95
  ary = []
89
96
 
90
- locker.lock.should be_false
97
+ expect(locker.lock).to be(false)
91
98
 
92
99
  th = Thread.new do
93
100
  locker.lock(:wait => true)
@@ -95,18 +102,18 @@ shared_examples_for 'ZK::Locker::Semaphore' do
95
102
  end
96
103
 
97
104
  locker.wait_until_blocked(5)
98
- locker.should be_waiting
99
- locker.should_not be_locked
100
- ary.should be_empty
105
+ expect(locker).to be_waiting
106
+ expect(locker).not_to be_locked
107
+ expect(ary).to be_empty
101
108
 
102
109
  zk.delete(@existing_locks.shuffle.first)
103
110
 
104
- th.join(2).should == th
111
+ expect(th.join(2)).to eq(th)
105
112
 
106
- ary.should_not be_empty
107
- ary.length.should == 1
113
+ expect(ary).not_to be_empty
114
+ expect(ary.length).to eq(1)
108
115
 
109
- locker.should be_locked
116
+ expect(locker).to be_locked
110
117
  end
111
118
  end
112
119
 
@@ -116,9 +123,9 @@ shared_examples_for 'ZK::Locker::Semaphore' do
116
123
 
117
124
  write_lock_dir = File.dirname(@existing_locks.first)
118
125
 
119
- zk.children(write_lock_dir).length.should == semaphore_size
126
+ expect(zk.children(write_lock_dir).length).to eq(semaphore_size)
120
127
 
121
- locker.lock.should be_false
128
+ expect(locker.lock).to be(false)
122
129
 
123
130
  th = Thread.new do
124
131
  begin
@@ -130,16 +137,16 @@ shared_examples_for 'ZK::Locker::Semaphore' do
130
137
  end
131
138
 
132
139
  locker.wait_until_blocked(5)
133
- locker.should be_waiting
134
- locker.should_not be_locked
135
- ary.should be_empty
140
+ expect(locker).to be_waiting
141
+ expect(locker).not_to be_locked
142
+ expect(ary).to be_empty
136
143
 
137
- th.join(2).should == th
144
+ expect(th.join(2)).to eq(th)
138
145
 
139
- zk.children(write_lock_dir).length.should == semaphore_size
146
+ expect(zk.children(write_lock_dir).length).to eq(semaphore_size)
140
147
 
141
- ary.should be_empty
142
- @exc.should be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
148
+ expect(ary).to be_empty
149
+ expect(@exc).to be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
143
150
  end
144
151
 
145
152
  end