zk 0.8.8 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +17 -0
- data/Gemfile +11 -0
- data/README.markdown +3 -5
- data/Rakefile +16 -0
- data/lib/z_k/client/state_mixin.rb +0 -2
- data/lib/z_k/client/unixisms.rb +27 -6
- data/lib/z_k/event_handler.rb +9 -2
- data/lib/z_k/extensions.rb +1 -0
- data/lib/z_k/version.rb +1 -1
- data/spec/informal/lock_with_dead_session.rb +80 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/z_k/client_spec.rb +124 -1
- data/zk.gemspec +0 -4
- metadata +7 -66
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -2,6 +2,17 @@
|
|
2
2
|
source ENV['MBOX_BUNDLER_SOURCE'] if ENV['MBOX_BUNDLER_SOURCE']
|
3
3
|
source "http://rubygems.org"
|
4
4
|
|
5
|
+
group :development do
|
6
|
+
gem 'pry'
|
7
|
+
end
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem 'rspec', '~> 2.8.0'
|
11
|
+
gem 'flexmock', '~> 0.8.10'
|
12
|
+
gem 'ZenTest', '~> 4.5.0'
|
13
|
+
gem 'rake'
|
14
|
+
end
|
15
|
+
|
5
16
|
# Specify your gem's dependencies in zk.gemspec
|
6
17
|
gemspec
|
7
18
|
|
data/README.markdown
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# ZK
|
2
2
|
|
3
|
-
ZK is a high-level interface to the Apache [ZooKeeper][] server. It is based on the [zookeeper gem][] which is a multi-Ruby low-level driver. Currently MRI 1.8.7, 1.9.2, and JRuby are supported (rubinius 1.2 is experimental but _should_ work). It is licensed under the [MIT][] license.
|
4
|
-
|
5
|
-
Note: 1.9.3-p0 support is currently under development, there are a few bugs to work out still...
|
3
|
+
ZK is a high-level interface to the Apache [ZooKeeper][] server. It is based on the [zookeeper gem][] which is a multi-Ruby low-level driver. Currently MRI 1.8.7, 1.9.2, 1.9.3, and JRuby are supported (rubinius 1.2 is experimental but _should_ work). It is licensed under the [MIT][] license.
|
6
4
|
|
7
5
|
This library is heavily used in a production deployment and is actively developed and maintained.
|
8
6
|
|
@@ -35,13 +33,13 @@ The [zookeeper gem][] provides a low-level, cross platform library for interfaci
|
|
35
33
|
ZK provides:
|
36
34
|
|
37
35
|
* a robust lock implementation (both shared and exclusive locks)
|
38
|
-
* an extension for the [Mongoid][] ORM to provide advisory locks on mongodb records
|
39
36
|
* a leader election implementation with both "leader" and "observer" roles
|
40
37
|
* a higher-level interface to the ZooKeeper callback/watcher mechanism than the [zookeeper gem][] provides
|
41
38
|
* a simple threadpool implementation
|
42
39
|
* a bounded, dynamically-growable (threadsafe) client pool implementation
|
43
40
|
* a recursive Find class (like the Find module in ruby-core)
|
44
41
|
* unix-like rm\_rf and mkdir\_p methods (useful for functional testing)
|
42
|
+
* an extension for the [Mongoid][] ORM to provide advisory locks on mongodb records
|
45
43
|
|
46
44
|
In addition to all of that, I would like to think that the public API the ZK::Client provides is more convenient to use for the common (synchronous) case. For use with [EventMachine][] there is [zk-eventmachine][] which provides a convenient API for writing evented code that uses the ZooKeeper server.
|
47
45
|
|
@@ -58,7 +56,7 @@ ZK strives to be a complete, correct, and convenient way of interacting with Zoo
|
|
58
56
|
|
59
57
|
* ZK::Client supports asynchronous calls of all basic methods (get, set, delete, etc.) however these versions are kind of inconvenient to use. For a fully evented stack, try [zk-eventmachine][], which is designed to be compatible and convenient to use in event-driven code.
|
60
58
|
|
61
|
-
* ZooKeeper "chroot" [connection syntax][chroot]
|
59
|
+
* ZooKeeper "chroot" [connection syntax][chroot] is currently being developed and should work for most cases. Right now we require that the root path exist before the chrooted client is used, but that may change [in the near future](https://github.com/slyphon/zk/issues/7).
|
62
60
|
|
63
61
|
* I am currently in the process of cleaning up the API documentation and converting it to use [YARD][].
|
64
62
|
|
data/Rakefile
CHANGED
@@ -31,3 +31,19 @@ gemset_name = 'zk'
|
|
31
31
|
task "mb:test_all" => rspec_task_name
|
32
32
|
end
|
33
33
|
|
34
|
+
namespace :spec do
|
35
|
+
task :define do
|
36
|
+
require 'rubygems'
|
37
|
+
require 'bundler/setup'
|
38
|
+
require 'rspec/core/rake_task'
|
39
|
+
|
40
|
+
RSpec::Core::RakeTask.new('spec:runner')
|
41
|
+
end
|
42
|
+
|
43
|
+
task :run => :define do
|
44
|
+
Rake::Task['spec:runner'].invoke
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
task :default => 'spec:run'
|
49
|
+
|
data/lib/z_k/client/unixisms.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module ZK
|
2
2
|
module Client
|
3
3
|
module Unixisms
|
4
|
+
include ZookeeperConstants
|
5
|
+
|
4
6
|
# Creates all parent paths and 'path' in zookeeper as persistent nodes with
|
5
7
|
# zero data.
|
6
8
|
#
|
@@ -62,7 +64,7 @@ module ZK
|
|
62
64
|
# watcher, you *will* deadlock!
|
63
65
|
def block_until_node_deleted(abs_node_path)
|
64
66
|
queue = Queue.new
|
65
|
-
|
67
|
+
subs = []
|
66
68
|
|
67
69
|
node_deletion_cb = lambda do |event|
|
68
70
|
if event.node_deleted?
|
@@ -72,16 +74,35 @@ module ZK
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
|
77
|
+
subs << event_handler.register(abs_node_path, &node_deletion_cb)
|
78
|
+
|
79
|
+
# NOTE: this pattern may be necessary for other features with blocking semantics!
|
80
|
+
|
81
|
+
session_cb = lambda do |event|
|
82
|
+
queue.enq(event.state)
|
83
|
+
end
|
76
84
|
|
85
|
+
[:expired_session, :connecting, :closed].each do |sym|
|
86
|
+
subs << event_handler.register_state_handler(sym, &session_cb)
|
87
|
+
end
|
88
|
+
|
77
89
|
# set up the callback, but bail if we don't need to wait
|
78
90
|
return true unless exists?(abs_node_path, :watch => true)
|
79
91
|
|
80
|
-
queue.pop
|
81
|
-
|
92
|
+
case queue.pop
|
93
|
+
when :deleted
|
94
|
+
true
|
95
|
+
when ZOO_EXPIRED_SESSION_STATE
|
96
|
+
raise ZookeeperExceptions::ZookeeperException::SessionExpired
|
97
|
+
when ZOO_CONNECTING_STATE
|
98
|
+
raise ZookeeperExceptions::ZookeeperException::NotConnected
|
99
|
+
when ZOO_CLOSED_STATE
|
100
|
+
raise ZookeeperExceptions::ZookeeperException::ConnectionClosed
|
101
|
+
else
|
102
|
+
raise "Hit unexpected case in block_until_node_deleted"
|
103
|
+
end
|
82
104
|
ensure
|
83
|
-
|
84
|
-
ev_sub.unregister if ev_sub
|
105
|
+
subs.each(&:unregister)
|
85
106
|
end
|
86
107
|
end
|
87
108
|
end
|
data/lib/z_k/event_handler.rb
CHANGED
@@ -85,9 +85,16 @@ module ZK
|
|
85
85
|
end
|
86
86
|
alias :subscribe :register
|
87
87
|
|
88
|
-
#
|
88
|
+
# Registers a "state of the connection" handler
|
89
89
|
#
|
90
|
-
#
|
90
|
+
# Valid states are: connecting, associating, connected, auth_failed,
|
91
|
+
# expired_session. Of all of these, you are probably most likely
|
92
|
+
# interested in `expired_session` and `connecting`, which are fired
|
93
|
+
# when you either lose your session (and have to completely reconnect),
|
94
|
+
# or when there's a temporary loss in connection and Zookeeper recommends
|
95
|
+
# you go into 'safe mode'.
|
96
|
+
#
|
97
|
+
# @param [String] state The state you want to register for.
|
91
98
|
# @param [Block] block the block to execute on state changes
|
92
99
|
# @yield [event] yields your block with
|
93
100
|
#
|
data/lib/z_k/extensions.rb
CHANGED
data/lib/z_k/version.rb
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'zk'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
$stderr.sync = true
|
7
|
+
|
8
|
+
ZK.logger = log = Logger.new('informal.log').tap { |l| l.level = Logger::DEBUG }
|
9
|
+
Zookeeper.logger = log
|
10
|
+
Zookeeper.set_debug_level(4)
|
11
|
+
|
12
|
+
class ::Exception
|
13
|
+
def to_std_format
|
14
|
+
"#{self.class}: #{message}\n" + backtrace {|n| "\t#{n}"}.join("\n")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def safe_join(th, timeout=nil)
|
19
|
+
begin
|
20
|
+
th.join(timeout)
|
21
|
+
rescue Exception => e
|
22
|
+
$stderr.puts "#{th[:name]} raised #{e.to_std_format}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def print_error
|
27
|
+
yield
|
28
|
+
rescue Exception => e
|
29
|
+
$stderr.puts "caught exception in #{Thread.current[:name]}: #{e.to_std_format}"
|
30
|
+
end
|
31
|
+
|
32
|
+
lock_name = 'the_big_sleep'
|
33
|
+
|
34
|
+
q = Queue.new
|
35
|
+
|
36
|
+
|
37
|
+
th1 = Thread.new do
|
38
|
+
print_error do
|
39
|
+
ZK.open do |zk|
|
40
|
+
$stderr.puts "first connection session_id: 0x%x" % zk.session_id
|
41
|
+
sub = zk.on_expired_session do |state|
|
42
|
+
$stderr.puts "OH NOES! thread 1 got an expired session! #{state.inspect}"
|
43
|
+
end
|
44
|
+
|
45
|
+
zk.with_lock(lock_name) do
|
46
|
+
q.push(:ok_sleeping)
|
47
|
+
sleep # we now sleep with the fishes
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
th1[:name] = 'thread 1'
|
54
|
+
|
55
|
+
q.pop
|
56
|
+
|
57
|
+
Thread.pass until th1.status == 'sleep'
|
58
|
+
|
59
|
+
$stderr.puts "ok, now try to acquire lock"
|
60
|
+
|
61
|
+
th2 = Thread.new do
|
62
|
+
print_error do
|
63
|
+
ZK.open do |zk|
|
64
|
+
$stderr.puts "second connection session_id: 0x%x" % zk.session_id
|
65
|
+
|
66
|
+
sub = zk.on_expired_session do |state|
|
67
|
+
$stderr.puts "OH NOES! thread 2 got an expired session! #{state.inspect}"
|
68
|
+
end
|
69
|
+
|
70
|
+
zk.with_lock(lock_name) do
|
71
|
+
$stderr.puts "acquired the lock in second thread"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
th2[:name] = 'thread 2'
|
78
|
+
|
79
|
+
[th1, th2].each(&method(:safe_join))
|
80
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -11,7 +11,9 @@ ZK_TEST_PORT = 2181
|
|
11
11
|
LOG_FILE = File.open(File.join(ZK::ZK_ROOT, 'test.log'), 'a').tap { |f| f.sync = true }
|
12
12
|
|
13
13
|
ZK.logger = Logger.new(LOG_FILE).tap { |log| log.level = Logger::DEBUG }
|
14
|
-
|
14
|
+
Zookeeper.logger = ZK.logger
|
15
|
+
|
16
|
+
ZK.logger.debug { "LOG OPEN" }
|
15
17
|
|
16
18
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
17
19
|
# in spec/support/ and its subdirectories.
|
data/spec/z_k/client_spec.rb
CHANGED
@@ -2,7 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ZK::Client do
|
4
4
|
before do
|
5
|
-
@
|
5
|
+
@connection_string = "localhost:#{ZK_TEST_PORT}"
|
6
|
+
@zk = ZK.new(@connection_string)
|
6
7
|
wait_until{ @zk.connected? }
|
7
8
|
@zk.rm_rf('/test')
|
8
9
|
end
|
@@ -82,6 +83,7 @@ describe ZK::Client do
|
|
82
83
|
@a = false
|
83
84
|
|
84
85
|
th = Thread.new do
|
86
|
+
|
85
87
|
@zk.block_until_node_deleted(@path)
|
86
88
|
@a = true
|
87
89
|
end
|
@@ -94,6 +96,69 @@ describe ZK::Client do
|
|
94
96
|
wait_until(2) { @a }
|
95
97
|
@a.should be_true
|
96
98
|
end
|
99
|
+
|
100
|
+
shared_examples_for 'session death' do
|
101
|
+
def deliver_session_event_to(event_num, zk)
|
102
|
+
# jeez, Zookeeper callbacks are so frustratingly stupid
|
103
|
+
bogus_event = ZookeeperCallbacks::WatcherCallback.new
|
104
|
+
bogus_event.initialize_context(:type => -1, :state => event_num, :path => '', :context => 'bogustestevent')
|
105
|
+
# XXX: this is bad because we're in the wrong thread, but we'll fix this after the next Zookeeper release
|
106
|
+
zk.event_handler.process(bogus_event)
|
107
|
+
end
|
108
|
+
|
109
|
+
before do
|
110
|
+
@other_zk = ZK.new(@connection_string)
|
111
|
+
end
|
112
|
+
|
113
|
+
after do
|
114
|
+
@other_zk.close! unless @other_zk.closed?
|
115
|
+
end
|
116
|
+
|
117
|
+
it %[should wake up in the case of an expired session and throw an exception] do
|
118
|
+
@a = false
|
119
|
+
|
120
|
+
@other_zk.event_handler.register_state_handler(zoo_state) do |event|
|
121
|
+
@a = event
|
122
|
+
end
|
123
|
+
|
124
|
+
th = Thread.new do
|
125
|
+
@other_zk.block_until_node_deleted(@path)
|
126
|
+
end
|
127
|
+
|
128
|
+
wait_until(2) { th.status == 'sleep' }
|
129
|
+
|
130
|
+
# not on the other thread, this may be bad
|
131
|
+
deliver_session_event_to(zoo_state, @other_zk)
|
132
|
+
|
133
|
+
# ditto, this is probably happening synchrnously
|
134
|
+
wait_until(2) { @a }
|
135
|
+
|
136
|
+
lambda { th.join(2) }.should raise_error(zoo_error_class)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'exceptional conditions' do
|
141
|
+
describe 'ZOO_EXPIRED_SESSION_STATE' do
|
142
|
+
let(:zoo_state) { ZookeeperConstants::ZOO_EXPIRED_SESSION_STATE }
|
143
|
+
let(:zoo_error_class) { ZookeeperExceptions::ZookeeperException::SessionExpired }
|
144
|
+
|
145
|
+
it_behaves_like 'session death'
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'ZOO_CONNECTING_STATE' do
|
149
|
+
let(:zoo_state) { ZookeeperConstants::ZOO_CONNECTING_STATE }
|
150
|
+
let(:zoo_error_class) { ZookeeperExceptions::ZookeeperException::NotConnected }
|
151
|
+
|
152
|
+
it_behaves_like 'session death'
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'ZOO_CLOSED_STATE' do
|
156
|
+
let(:zoo_state) { ZookeeperConstants::ZOO_CLOSED_STATE }
|
157
|
+
let(:zoo_error_class) { ZookeeperExceptions::ZookeeperException::ConnectionClosed }
|
158
|
+
|
159
|
+
it_behaves_like 'session death'
|
160
|
+
end
|
161
|
+
end
|
97
162
|
end
|
98
163
|
end
|
99
164
|
|
@@ -106,6 +171,64 @@ describe ZK::Client do
|
|
106
171
|
@zk.session_passwd.should be_kind_of(String)
|
107
172
|
end
|
108
173
|
end
|
174
|
+
|
175
|
+
describe 'reopen' do
|
176
|
+
describe 'watchers' do
|
177
|
+
before do
|
178
|
+
@path = '/testwatchers'
|
179
|
+
@queue = Queue.new
|
180
|
+
end
|
181
|
+
|
182
|
+
after do
|
183
|
+
@zk.delete(@path)
|
184
|
+
end
|
185
|
+
|
186
|
+
def ensure_event_delivery!
|
187
|
+
@sub ||= @zk.event_handler.register(@path) do |event|
|
188
|
+
logger.debug { "got event: #{event.inspect}" }
|
189
|
+
@queue << event
|
190
|
+
end
|
191
|
+
|
192
|
+
@zk.exists?(@path, :watch => true).should be_false
|
193
|
+
@zk.create(@path, '')
|
194
|
+
|
195
|
+
logger.debug { "waiting for event delivery" }
|
196
|
+
|
197
|
+
wait_until(2) do
|
198
|
+
begin
|
199
|
+
@events << @queue.pop(true)
|
200
|
+
true
|
201
|
+
rescue ThreadError
|
202
|
+
false
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# first watch delivered correctly
|
207
|
+
@events.length.should > 0
|
208
|
+
end
|
209
|
+
|
210
|
+
it %[should fire re-registered watchers after reopen (#9)] do
|
211
|
+
@events = []
|
212
|
+
|
213
|
+
logger.debug { "ensure event delivery" }
|
214
|
+
ensure_event_delivery!
|
215
|
+
|
216
|
+
logger.debug { "reopening connection" }
|
217
|
+
@zk.reopen
|
218
|
+
|
219
|
+
wait_until(2) { @zk.connected? }
|
220
|
+
|
221
|
+
logger.debug { "deleting path" }
|
222
|
+
@zk.delete(@path)
|
223
|
+
|
224
|
+
logger.debug { "clearing events" }
|
225
|
+
@events.clear
|
226
|
+
|
227
|
+
logger.debug { "taunt them a second time" }
|
228
|
+
ensure_event_delivery!
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
109
232
|
end
|
110
233
|
|
111
234
|
|
data/zk.gemspec
CHANGED
@@ -14,10 +14,6 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.add_runtime_dependency 'slyphon-zookeeper', '~> 0.3.0'
|
16
16
|
|
17
|
-
s.add_development_dependency 'rspec', '~> 2.8.0'
|
18
|
-
s.add_development_dependency 'flexmock', '~> 0.8.10'
|
19
|
-
s.add_development_dependency 'ZenTest', '~> 4.5.0'
|
20
|
-
s.add_development_dependency 'pry'
|
21
17
|
|
22
18
|
s.files = `git ls-files`.split("\n")
|
23
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
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: 45
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 9
|
10
|
+
version: 0.8.9
|
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-04-
|
19
|
+
date: 2012-04-21 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: slyphon-zookeeper
|
@@ -34,68 +34,6 @@ dependencies:
|
|
34
34
|
version: 0.3.0
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: rspec
|
39
|
-
prerelease: false
|
40
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 47
|
46
|
-
segments:
|
47
|
-
- 2
|
48
|
-
- 8
|
49
|
-
- 0
|
50
|
-
version: 2.8.0
|
51
|
-
type: :development
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: flexmock
|
55
|
-
prerelease: false
|
56
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
hash: 43
|
62
|
-
segments:
|
63
|
-
- 0
|
64
|
-
- 8
|
65
|
-
- 10
|
66
|
-
version: 0.8.10
|
67
|
-
type: :development
|
68
|
-
version_requirements: *id003
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: ZenTest
|
71
|
-
prerelease: false
|
72
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
hash: 43
|
78
|
-
segments:
|
79
|
-
- 4
|
80
|
-
- 5
|
81
|
-
- 0
|
82
|
-
version: 4.5.0
|
83
|
-
type: :development
|
84
|
-
version_requirements: *id004
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: pry
|
87
|
-
prerelease: false
|
88
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ">="
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
hash: 3
|
94
|
-
segments:
|
95
|
-
- 0
|
96
|
-
version: "0"
|
97
|
-
type: :development
|
98
|
-
version_requirements: *id005
|
99
37
|
description: |
|
100
38
|
A high-level wrapper around the zookeeper driver
|
101
39
|
|
@@ -112,6 +50,7 @@ files:
|
|
112
50
|
- .dotfiles/rspec-logging
|
113
51
|
- .dotfiles/rvmrc
|
114
52
|
- .gitignore
|
53
|
+
- .travis.yml
|
115
54
|
- .yardopts
|
116
55
|
- Gemfile
|
117
56
|
- LICENSE
|
@@ -138,6 +77,7 @@ files:
|
|
138
77
|
- lib/z_k/threadpool.rb
|
139
78
|
- lib/z_k/version.rb
|
140
79
|
- lib/zk.rb
|
80
|
+
- spec/informal/lock_with_dead_session.rb
|
141
81
|
- spec/log4j.properties
|
142
82
|
- spec/message_queue_spec.rb
|
143
83
|
- spec/spec_helper.rb
|
@@ -189,6 +129,7 @@ signing_key:
|
|
189
129
|
specification_version: 3
|
190
130
|
summary: A high-level wrapper around the zookeeper driver
|
191
131
|
test_files:
|
132
|
+
- spec/informal/lock_with_dead_session.rb
|
192
133
|
- spec/log4j.properties
|
193
134
|
- spec/message_queue_spec.rb
|
194
135
|
- spec/spec_helper.rb
|