zk 1.9.6 → 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.
- checksums.yaml +5 -13
 - data/.github/workflows/build.yml +55 -0
 - data/Gemfile +15 -6
 - data/README.markdown +9 -9
 - data/RELEASES.markdown +10 -1
 - data/lib/zk/client.rb +1 -1
 - data/lib/zk/event_handler.rb +15 -7
 - data/lib/zk/fork_hook.rb +2 -2
 - data/lib/zk/locker/locker_base.rb +13 -0
 - data/lib/zk/locker/semaphore.rb +1 -3
 - data/lib/zk/node_deletion_watcher.rb +3 -4
 - data/lib/zk/pool.rb +11 -11
 - data/lib/zk/version.rb +1 -1
 - data/spec/event_catcher_spec.rb +1 -1
 - data/spec/message_queue_spec.rb +6 -6
 - data/spec/shared/client_examples.rb +81 -81
 - data/spec/shared/locker_examples.rb +13 -13
 - data/spec/spec_helper.rb +10 -11
 - data/spec/zk/00_forked_client_integration_spec.rb +3 -3
 - data/spec/zk/client/locking_and_session_death_spec.rb +2 -2
 - data/spec/zk/client_spec.rb +19 -19
 - data/spec/zk/election_spec.rb +44 -44
 - data/spec/zk/extensions_spec.rb +2 -2
 - data/spec/zk/locker/exclusive_locker_spec.rb +41 -41
 - data/spec/zk/locker/locker_basic_spec.rb +55 -33
 - data/spec/zk/locker/semaphore_spec.rb +39 -32
 - data/spec/zk/locker/shared_exclusive_integration_spec.rb +37 -37
 - data/spec/zk/locker/shared_locker_spec.rb +43 -43
 - data/spec/zk/locker_spec.rb +2 -2
 - data/spec/zk/module_spec.rb +25 -25
 - data/spec/zk/mongoid_spec.rb +47 -47
 - data/spec/zk/node_deletion_watcher_spec.rb +39 -31
 - data/spec/zk/pool_spec.rb +56 -65
 - data/spec/zk/threaded_callback_spec.rb +10 -10
 - data/spec/zk/threadpool_spec.rb +25 -25
 - data/spec/zk/watch_spec.rb +67 -79
 - data/spec/zk/zookeeper_spec.rb +31 -31
 - data/zk.gemspec +1 -1
 - metadata +23 -24
 - data/.travis.yml +0 -30
 
| 
         @@ -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. 
     | 
| 
      
 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. 
     | 
| 
       32 
     | 
    
         
            -
                @zk2.locker(@path_to_lock).lock. 
     | 
| 
      
 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. 
     | 
| 
      
 36 
     | 
    
         
            +
                expect(@zk.locker(@path_to_lock).assert).to be(false)
         
     | 
| 
       37 
37 
     | 
    
         
             
                l = @zk2.locker(@path_to_lock)
         
     | 
| 
       38 
     | 
    
         
            -
                l.lock. 
     | 
| 
       39 
     | 
    
         
            -
                l.assert. 
     | 
| 
      
 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. 
     | 
| 
       47 
     | 
    
         
            -
                lock2.lock. 
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                expect(lock1.lock).to be(true)
         
     | 
| 
      
 47 
     | 
    
         
            +
                expect(lock2.lock).to be(false)
         
     | 
| 
       48 
48 
     | 
    
         
             
                lock1.unlock
         
     | 
| 
       49 
     | 
    
         
            -
                lock2.lock. 
     | 
| 
      
 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. 
     | 
| 
       57 
     | 
    
         
            -
                lock2.lock. 
     | 
| 
      
 56 
     | 
    
         
            +
                expect(lock1.lock).to be(true)
         
     | 
| 
      
 57 
     | 
    
         
            +
                expect(lock2.lock).to be(false)
         
     | 
| 
       58 
58 
     | 
    
         
             
                @zk.close!
         
     | 
| 
       59 
     | 
    
         
            -
                lock2.lock. 
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
       74 
     | 
    
         
            -
                      lock. 
     | 
| 
       75 
     | 
    
         
            -
                       
     | 
| 
      
 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. 
     | 
| 
       82 
     | 
    
         
            -
                      lock. 
     | 
| 
       83 
     | 
    
         
            -
                       
     | 
| 
      
 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. 
     | 
| 
      
 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). 
     | 
| 
       102 
     | 
    
         
            -
                    @exc. 
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
      
 117 
     | 
    
         
            +
                      expect(array.length).to eq(2)
         
     | 
| 
       118 
118 
     | 
    
         
             
                    end
         
     | 
| 
       119 
119 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                    array.length. 
     | 
| 
      
 120 
     | 
    
         
            +
                    expect(array.length).to eq(1)
         
     | 
| 
       121 
121 
     | 
    
         
             
                    first_lock.unlock
         
     | 
| 
       122 
122 
     | 
    
         
             
                    thread.join(10)
         
     | 
| 
       123 
     | 
    
         
            -
                    array.length. 
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
       144 
     | 
    
         
            -
                    thread.join(2). 
     | 
| 
       145 
     | 
    
         
            -
                    @exc. 
     | 
| 
       146 
     | 
    
         
            -
                    @exc. 
     | 
| 
      
 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. 
     | 
| 
      
 24 
     | 
    
         
            +
                    expect(locker).to be_acquirable
         
     | 
| 
       18 
25 
     | 
    
         
             
                  end
         
     | 
| 
       19 
26 
     | 
    
         | 
| 
       20 
27 
     | 
    
         
             
                  it %[should check local state of lockedness] do
         
     | 
| 
       21 
     | 
    
         
            -
                    locker.lock. 
     | 
| 
       22 
     | 
    
         
            -
                    locker. 
     | 
| 
      
 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. 
     | 
| 
       27 
     | 
    
         
            -
                    locker. 
     | 
| 
       28 
     | 
    
         
            -
                    locker2.lock. 
     | 
| 
       29 
     | 
    
         
            -
                    locker. 
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
       45 
     | 
    
         
            -
                    locker. 
     | 
| 
      
 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. 
     | 
| 
       50 
     | 
    
         
            -
                    locker2. 
     | 
| 
      
 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. 
     | 
| 
      
 71 
     | 
    
         
            +
                    expect(@rval).to be(false)
         
     | 
| 
       65 
72 
     | 
    
         
             
                  end
         
     | 
| 
       66 
73 
     | 
    
         | 
| 
       67 
74 
     | 
    
         
             
                  it %[should not be locked] do
         
     | 
| 
       68 
     | 
    
         
            -
                    locker. 
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
      
 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. 
     | 
| 
       99 
     | 
    
         
            -
                      locker. 
     | 
| 
       100 
     | 
    
         
            -
                      ary. 
     | 
| 
      
 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). 
     | 
| 
      
 111 
     | 
    
         
            +
                      expect(th.join(2)).to eq(th)
         
     | 
| 
       105 
112 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
                      ary. 
     | 
| 
       107 
     | 
    
         
            -
                      ary.length. 
     | 
| 
      
 113 
     | 
    
         
            +
                      expect(ary).not_to be_empty
         
     | 
| 
      
 114 
     | 
    
         
            +
                      expect(ary.length).to eq(1)
         
     | 
| 
       108 
115 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
                      locker. 
     | 
| 
      
 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. 
     | 
| 
      
 126 
     | 
    
         
            +
                      expect(zk.children(write_lock_dir).length).to eq(semaphore_size)
         
     | 
| 
       120 
127 
     | 
    
         | 
| 
       121 
     | 
    
         
            -
                      locker.lock. 
     | 
| 
      
 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. 
     | 
| 
       134 
     | 
    
         
            -
                      locker. 
     | 
| 
       135 
     | 
    
         
            -
                      ary. 
     | 
| 
      
 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). 
     | 
| 
      
 144 
     | 
    
         
            +
                      expect(th.join(2)).to eq(th)
         
     | 
| 
       138 
145 
     | 
    
         | 
| 
       139 
     | 
    
         
            -
                      zk.children(write_lock_dir).length. 
     | 
| 
      
 146 
     | 
    
         
            +
                      expect(zk.children(write_lock_dir).length).to eq(semaphore_size)
         
     | 
| 
       140 
147 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
                      ary. 
     | 
| 
       142 
     | 
    
         
            -
                      @exc. 
     | 
| 
      
 148 
     | 
    
         
            +
                      expect(ary).to be_empty
         
     | 
| 
      
 149 
     | 
    
         
            +
                      expect(@exc).to be_kind_of(ZK::Exceptions::LockWaitTimeoutError)
         
     | 
| 
       143 
150 
     | 
    
         
             
                    end
         
     | 
| 
       144 
151 
     | 
    
         | 
| 
       145 
152 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -8,12 +8,12 @@ shared_examples_for :shared_exclusive_integration do 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
              describe 'shared lock acquired first' do
         
     | 
| 
       10 
10 
     | 
    
         
             
                it %[should block exclusive locks from acquiring until released] do
         
     | 
| 
       11 
     | 
    
         
            -
                  @sh_lock.lock. 
     | 
| 
       12 
     | 
    
         
            -
                  @ex_lock.lock. 
     | 
| 
      
 11 
     | 
    
         
            +
                  expect(@sh_lock.lock).to be(true)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  expect(@ex_lock.lock).to be(false)
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  mutex = Monitor.new
         
     | 
| 
       15 
15 
     | 
    
         
             
                  cond = mutex.new_cond
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       17 
17 
     | 
    
         
             
                  th = Thread.new do
         
     | 
| 
       18 
18 
     | 
    
         
             
                    logger.debug { "@ex_lock trying to acquire acquire lock" }
         
     | 
| 
       19 
19 
     | 
    
         
             
                    @ex_lock.with_lock do
         
     | 
| 
         @@ -28,29 +28,29 @@ shared_examples_for :shared_exclusive_integration do 
     | 
|
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                  mutex.synchronize do
         
     | 
| 
       30 
30 
     | 
    
         
             
                    logger.debug { "unlocking the shared lock" }
         
     | 
| 
       31 
     | 
    
         
            -
                    @sh_lock.unlock. 
     | 
| 
      
 31 
     | 
    
         
            +
                    expect(@sh_lock.unlock).to be(true)
         
     | 
| 
       32 
32 
     | 
    
         
             
                    cond.wait_until { th[:got_lock] }   # make sure they actually received the lock (avoid race)
         
     | 
| 
       33 
     | 
    
         
            -
                    th[:got_lock]. 
     | 
| 
      
 33 
     | 
    
         
            +
                    expect(th[:got_lock]).to be(true)
         
     | 
| 
       34 
34 
     | 
    
         
             
                    logger.debug { "ok, they got the lock" }
         
     | 
| 
       35 
35 
     | 
    
         
             
                  end
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                  th.join(5). 
     | 
| 
      
 37 
     | 
    
         
            +
                  expect(th.join(5)).to eq(th)
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
                  logger.debug { "thread joined, exclusive lock should be releasd" }
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                  @ex_lock. 
     | 
| 
      
 41 
     | 
    
         
            +
                  expect(@ex_lock).not_to be_locked
         
     | 
| 
       42 
42 
     | 
    
         
             
                end
         
     | 
| 
       43 
43 
     | 
    
         
             
              end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
              describe 'multiple shared locks acquired first' do
         
     | 
| 
       46 
46 
     | 
    
         
             
                before do
         
     | 
| 
       47 
     | 
    
         
            -
                  zk3. 
     | 
| 
       48 
     | 
    
         
            -
                  @sh_lock2 = ZK::Locker.shared_locker(zk3, path) 
     | 
| 
      
 47 
     | 
    
         
            +
                  expect(zk3).not_to be_nil
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @sh_lock2 = ZK::Locker.shared_locker(zk3, path)
         
     | 
| 
       49 
49 
     | 
    
         
             
                end
         
     | 
| 
       50 
50 
     | 
    
         
             
                it %[should not aquire a lock when highest-numbered released but others remain] do
         
     | 
| 
       51 
     | 
    
         
            -
                  @sh_lock.lock. 
     | 
| 
       52 
     | 
    
         
            -
                  @sh_lock2.lock. 
     | 
| 
       53 
     | 
    
         
            -
                  @ex_lock.lock. 
     | 
| 
      
 51 
     | 
    
         
            +
                  expect(@sh_lock.lock).to be(true)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  expect(@sh_lock2.lock).to be(true)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  expect(@ex_lock.lock).to be(false)
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
                  mutex = Monitor.new
         
     | 
| 
       56 
56 
     | 
    
         
             
                  cond = mutex.new_cond
         
     | 
| 
         @@ -75,28 +75,28 @@ shared_examples_for :shared_exclusive_integration do 
     | 
|
| 
       75 
75 
     | 
    
         
             
                  mutex.synchronize do
         
     | 
| 
       76 
76 
     | 
    
         
             
                    @ex_lock.wait_until_blocked(1)
         
     | 
| 
       77 
77 
     | 
    
         
             
                    logger.debug { "unlocking the highest shared lock" }
         
     | 
| 
       78 
     | 
    
         
            -
                    @sh_lock2.unlock. 
     | 
| 
      
 78 
     | 
    
         
            +
                    expect(@sh_lock2.unlock).to be(true)
         
     | 
| 
       79 
79 
     | 
    
         
             
                    cond.wait_until { (!th[:got_lock].nil?) }   # make sure they actually received the lock (avoid race)
         
     | 
| 
       80 
     | 
    
         
            -
                    th[:got_lock]. 
     | 
| 
      
 80 
     | 
    
         
            +
                    expect(th[:got_lock]).to be(false)
         
     | 
| 
       81 
81 
     | 
    
         
             
                    logger.debug { "they didn't get the lock." }
         
     | 
| 
       82 
82 
     | 
    
         
             
                  end
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
       84 
     | 
    
         
            -
                  th.join(5). 
     | 
| 
      
 84 
     | 
    
         
            +
                  expect(th.join(5)).to eq(th)
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
       86 
86 
     | 
    
         
             
                  logger.debug { "thread joined, exclusive lock should be releasd" }
         
     | 
| 
       87 
     | 
    
         
            -
                  @sh_lock.unlock. 
     | 
| 
       88 
     | 
    
         
            -
                  @ex_lock. 
     | 
| 
      
 87 
     | 
    
         
            +
                  expect(@sh_lock.unlock).to be(true)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  expect(@ex_lock).not_to be_locked
         
     | 
| 
       89 
89 
     | 
    
         
             
                end
         
     | 
| 
       90 
90 
     | 
    
         
             
              end
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
       92 
92 
     | 
    
         
             
              describe 'exclusive lock acquired first' do
         
     | 
| 
       93 
93 
     | 
    
         
             
                it %[should block shared lock from acquiring until released] do
         
     | 
| 
       94 
     | 
    
         
            -
                  @ex_lock.lock. 
     | 
| 
       95 
     | 
    
         
            -
                  @sh_lock.lock. 
     | 
| 
      
 94 
     | 
    
         
            +
                  expect(@ex_lock.lock).to be(true)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  expect(@sh_lock.lock).to be(false)
         
     | 
| 
       96 
96 
     | 
    
         | 
| 
       97 
97 
     | 
    
         
             
                  mutex = Monitor.new
         
     | 
| 
       98 
98 
     | 
    
         
             
                  cond = mutex.new_cond
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
       100 
100 
     | 
    
         
             
                  th = Thread.new do
         
     | 
| 
       101 
101 
     | 
    
         
             
                    logger.debug { "@ex_lock trying to acquire acquire lock" }
         
     | 
| 
       102 
102 
     | 
    
         
             
                    @sh_lock.with_lock do
         
     | 
| 
         @@ -111,31 +111,31 @@ shared_examples_for :shared_exclusive_integration do 
     | 
|
| 
       111 
111 
     | 
    
         | 
| 
       112 
112 
     | 
    
         
             
                  mutex.synchronize do
         
     | 
| 
       113 
113 
     | 
    
         
             
                    logger.debug { "unlocking the shared lock" }
         
     | 
| 
       114 
     | 
    
         
            -
                    @ex_lock.unlock. 
     | 
| 
      
 114 
     | 
    
         
            +
                    expect(@ex_lock.unlock).to be(true)
         
     | 
| 
       115 
115 
     | 
    
         
             
                    cond.wait_until { th[:got_lock] }   # make sure they actually received the lock (avoid race)
         
     | 
| 
       116 
     | 
    
         
            -
                    th[:got_lock]. 
     | 
| 
      
 116 
     | 
    
         
            +
                    expect(th[:got_lock]).to be(true)
         
     | 
| 
       117 
117 
     | 
    
         
             
                    logger.debug { "ok, they got the lock" }
         
     | 
| 
       118 
118 
     | 
    
         
             
                  end
         
     | 
| 
       119 
119 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                  th.join(5). 
     | 
| 
      
 120 
     | 
    
         
            +
                  expect(th.join(5)).to eq(th)
         
     | 
| 
       121 
121 
     | 
    
         | 
| 
       122 
122 
     | 
    
         
             
                  logger.debug { "thread joined, exclusive lock should be releasd" }
         
     | 
| 
       123 
123 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                  @sh_lock. 
     | 
| 
      
 124 
     | 
    
         
            +
                  expect(@sh_lock).not_to be_locked
         
     | 
| 
       125 
125 
     | 
    
         
             
                end
         
     | 
| 
       126 
126 
     | 
    
         
             
              end
         
     | 
| 
       127 
127 
     | 
    
         | 
| 
       128 
128 
     | 
    
         
             
              describe 'shared-exclusive-shared' do
         
     | 
| 
       129 
129 
     | 
    
         
             
                before do
         
     | 
| 
       130 
     | 
    
         
            -
                  zk3. 
     | 
| 
       131 
     | 
    
         
            -
                  @sh_lock2 = ZK::Locker.shared_locker(zk3, path) 
     | 
| 
      
 130 
     | 
    
         
            +
                  expect(zk3).not_to be_nil
         
     | 
| 
      
 131 
     | 
    
         
            +
                  @sh_lock2 = ZK::Locker.shared_locker(zk3, path)
         
     | 
| 
       132 
132 
     | 
    
         
             
                end
         
     | 
| 
       133 
133 
     | 
    
         | 
| 
       134 
134 
     | 
    
         
             
                it %[should act something like a queue] do
         
     | 
| 
       135 
135 
     | 
    
         
             
                  @array = []
         
     | 
| 
       136 
136 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
                  @sh_lock.lock. 
     | 
| 
       138 
     | 
    
         
            -
                  @sh_lock. 
     | 
| 
      
 137 
     | 
    
         
            +
                  expect(@sh_lock.lock).to be(true)
         
     | 
| 
      
 138 
     | 
    
         
            +
                  expect(@sh_lock).to be_locked
         
     | 
| 
       139 
139 
     | 
    
         | 
| 
       140 
140 
     | 
    
         
             
                  ex_th = Thread.new do
         
     | 
| 
       141 
141 
     | 
    
         
             
                    begin
         
     | 
| 
         @@ -150,15 +150,15 @@ shared_examples_for :shared_exclusive_integration do 
     | 
|
| 
       150 
150 
     | 
    
         
             
                  logger.debug { "about to wait for @ex_lock to be blocked" }
         
     | 
| 
       151 
151 
     | 
    
         | 
| 
       152 
152 
     | 
    
         
             
                  @ex_lock.wait_until_blocked(5)
         
     | 
| 
       153 
     | 
    
         
            -
                  @ex_lock. 
     | 
| 
      
 153 
     | 
    
         
            +
                  expect(@ex_lock).to be_waiting
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
       155 
155 
     | 
    
         
             
                  logger.debug { "@ex_lock is waiting" }
         
     | 
| 
       156 
156 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
                  @ex_lock. 
     | 
| 
      
 157 
     | 
    
         
            +
                  expect(@ex_lock).not_to be_locked
         
     | 
| 
       158 
158 
     | 
    
         | 
| 
       159 
159 
     | 
    
         
             
                  # this is the important one, does the second shared lock get blocked by
         
     | 
| 
       160 
160 
     | 
    
         
             
                  # the exclusive lock
         
     | 
| 
       161 
     | 
    
         
            -
                  @sh_lock2.lock. 
     | 
| 
      
 161 
     | 
    
         
            +
                  expect(@sh_lock2.lock).not_to be(true)
         
     | 
| 
       162 
162 
     | 
    
         | 
| 
       163 
163 
     | 
    
         
             
                  sh2_th = Thread.new do
         
     | 
| 
       164 
164 
     | 
    
         
             
                    begin
         
     | 
| 
         @@ -173,19 +173,19 @@ shared_examples_for :shared_exclusive_integration do 
     | 
|
| 
       173 
173 
     | 
    
         
             
                  logger.debug { "about to wait for @sh_lock2 to be blocked" }
         
     | 
| 
       174 
174 
     | 
    
         | 
| 
       175 
175 
     | 
    
         
             
                  @sh_lock2.wait_until_blocked(5)
         
     | 
| 
       176 
     | 
    
         
            -
                  @sh_lock2. 
     | 
| 
      
 176 
     | 
    
         
            +
                  expect(@sh_lock2).to be_waiting
         
     | 
| 
       177 
177 
     | 
    
         | 
| 
       178 
178 
     | 
    
         
             
                  logger.debug { "@sh_lock2 is waiting" }
         
     | 
| 
       179 
179 
     | 
    
         | 
| 
       180 
180 
     | 
    
         
             
                  # ok, now unlock the first in the chain
         
     | 
| 
       181 
181 
     | 
    
         
             
                  @sh_lock.assert!
         
     | 
| 
       182 
     | 
    
         
            -
                  @sh_lock.unlock. 
     | 
| 
      
 182 
     | 
    
         
            +
                  expect(@sh_lock.unlock).to be(true)
         
     | 
| 
       183 
183 
     | 
    
         | 
| 
       184 
     | 
    
         
            -
                  ex_th.join(5). 
     | 
| 
       185 
     | 
    
         
            -
                  sh2_th.join(5). 
     | 
| 
      
 184 
     | 
    
         
            +
                  expect(ex_th.join(5)).to eq(ex_th)
         
     | 
| 
      
 185 
     | 
    
         
            +
                  expect(sh2_th.join(5)).to eq(sh2_th)
         
     | 
| 
       186 
186 
     | 
    
         | 
| 
       187 
     | 
    
         
            -
                  @array.length. 
     | 
| 
       188 
     | 
    
         
            -
                  @array. 
     | 
| 
      
 187 
     | 
    
         
            +
                  expect(@array.length).to eq(2)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  expect(@array).to eq([:ex_lock, :sh_lock2])
         
     | 
| 
       189 
189 
     | 
    
         
             
                end
         
     | 
| 
       190 
190 
     | 
    
         
             
              end
         
     | 
| 
       191 
191 
     | 
    
         
             
            end # shared_exclusive_integration
         
     |