zookeeper 0.9.4-java → 1.0.0.beta.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.dotfiles/rvmrc +1 -0
- data/.gitignore +3 -0
- data/.gitmodules +3 -0
- data/.travis.yml +22 -0
- data/CHANGELOG +38 -5
- data/Gemfile +18 -1
- data/README.markdown +2 -0
- data/Rakefile +47 -109
- data/ext/c_zookeeper.rb +10 -6
- data/ext/zookeeper_base.rb +23 -11
- data/ext/zookeeper_c.c +14 -10
- data/java/{zookeeper_base.rb → java_base.rb} +13 -12
- data/lib/zookeeper/acls.rb +17 -13
- data/lib/zookeeper/callbacks.rb +28 -11
- data/lib/zookeeper/client.rb +30 -0
- data/lib/zookeeper/client_methods.rb +241 -0
- data/lib/zookeeper/common/queue_with_pipe.rb +3 -7
- data/lib/zookeeper/common.rb +13 -12
- data/lib/zookeeper/compatibility.rb +135 -0
- data/lib/zookeeper/constants.rb +35 -1
- data/lib/zookeeper/em_client.rb +1 -1
- data/lib/zookeeper/exceptions.rb +117 -93
- data/lib/zookeeper/rake_tasks.rb +165 -0
- data/lib/zookeeper/stat.rb +16 -16
- data/lib/zookeeper/version.rb +2 -4
- data/lib/zookeeper.rb +32 -244
- data/scripts/upgrade-1.0-sed-alike.rb +46 -0
- data/spec/c_zookeeper_spec.rb +10 -9
- data/spec/chrooted_connection_spec.rb +2 -2
- data/spec/default_watcher_spec.rb +4 -4
- data/spec/em_spec.rb +1 -1
- data/spec/shared/connection_examples.rb +52 -37
- data/spec/spec_helper.rb +22 -84
- data/spec/support/00_spawn_zookeeper.rb +20 -0
- data/spec/support/zookeeper_spec_helpers.rb +84 -0
- data/spec/zookeeper_spec.rb +1 -1
- data/zookeeper.gemspec +9 -12
- metadata +50 -36
- data/examples/cloud_config.rb +0 -125
- data/test/test_basic.rb +0 -37
- data/test/test_callback1.rb +0 -36
- data/test/test_close.rb +0 -16
- data/test/test_esoteric.rb +0 -7
- data/test/test_watcher1.rb +0 -56
- data/test/test_watcher2.rb +0 -52
data/lib/zookeeper.rb
CHANGED
@@ -5,23 +5,27 @@ require 'monitor'
|
|
5
5
|
require 'forwardable'
|
6
6
|
require 'logger'
|
7
7
|
|
8
|
-
require '
|
9
|
-
require 'zookeeper/constants'
|
10
|
-
require 'zookeeper/callbacks'
|
11
|
-
require 'zookeeper/exceptions'
|
12
|
-
require 'zookeeper/stat'
|
13
|
-
require 'zookeeper/acls'
|
8
|
+
require 'backports'
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
$LOAD_PATH.unshift(File.expand_path('../java', File.dirname(__FILE__))).uniq!
|
18
|
-
else
|
19
|
-
$LOAD_PATH.unshift(File.expand_path('../ext', File.dirname(__FILE__))).uniq!
|
10
|
+
module Zookeeper
|
11
|
+
# establishes the namespace
|
20
12
|
end
|
21
13
|
|
22
|
-
|
14
|
+
require_relative 'zookeeper/acls'
|
15
|
+
require_relative 'zookeeper/constants'
|
16
|
+
require_relative 'zookeeper/exceptions'
|
17
|
+
require_relative 'zookeeper/common'
|
18
|
+
require_relative 'zookeeper/callbacks'
|
19
|
+
require_relative 'zookeeper/stat'
|
20
|
+
require_relative 'zookeeper/client_methods'
|
21
|
+
|
22
|
+
# ok, now we construct the client
|
23
|
+
|
24
|
+
require_relative 'zookeeper/client'
|
25
|
+
|
26
|
+
module Zookeeper
|
27
|
+
include Constants
|
23
28
|
|
24
|
-
class Zookeeper < ZookeeperBase
|
25
29
|
unless defined?(@@logger)
|
26
30
|
@@logger = Logger.new($stderr).tap { |l| l.level = Logger::ERROR }
|
27
31
|
end
|
@@ -34,167 +38,20 @@ class Zookeeper < ZookeeperBase
|
|
34
38
|
@@logger = logger
|
35
39
|
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def initialize(host, timeout=10, watcher=nil)
|
43
|
-
super
|
44
|
-
end
|
45
|
-
|
46
|
-
def get(options = {})
|
47
|
-
assert_open
|
48
|
-
assert_supported_keys(options, [:path, :watcher, :watcher_context, :callback, :callback_context])
|
49
|
-
assert_required_keys(options, [:path])
|
50
|
-
|
51
|
-
req_id = setup_call(:get, options)
|
52
|
-
rc, value, stat = super(req_id, options[:path], options[:callback], options[:watcher])
|
53
|
-
|
54
|
-
rv = { :req_id => req_id, :rc => rc }
|
55
|
-
options[:callback] ? rv : rv.merge(:data => value, :stat => Stat.new(stat))
|
56
|
-
end
|
57
|
-
|
58
|
-
def set(options = {})
|
59
|
-
assert_open
|
60
|
-
assert_supported_keys(options, [:path, :data, :version, :callback, :callback_context])
|
61
|
-
assert_required_keys(options, [:path])
|
62
|
-
assert_valid_data_size!(options[:data])
|
63
|
-
options[:version] ||= -1
|
64
|
-
|
65
|
-
req_id = setup_call(:set, options)
|
66
|
-
rc, stat = super(req_id, options[:path], options[:data], options[:callback], options[:version])
|
67
|
-
|
68
|
-
rv = { :req_id => req_id, :rc => rc }
|
69
|
-
options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
|
70
|
-
end
|
71
|
-
|
72
|
-
def get_children(options = {})
|
73
|
-
assert_open
|
74
|
-
assert_supported_keys(options, [:path, :callback, :callback_context, :watcher, :watcher_context])
|
75
|
-
assert_required_keys(options, [:path])
|
76
|
-
|
77
|
-
req_id = setup_call(:get_children, options)
|
78
|
-
rc, children, stat = super(req_id, options[:path], options[:callback], options[:watcher])
|
79
|
-
|
80
|
-
rv = { :req_id => req_id, :rc => rc }
|
81
|
-
options[:callback] ? rv : rv.merge(:children => children, :stat => Stat.new(stat))
|
82
|
-
end
|
83
|
-
|
84
|
-
def stat(options = {})
|
85
|
-
assert_open
|
86
|
-
assert_supported_keys(options, [:path, :callback, :callback_context, :watcher, :watcher_context])
|
87
|
-
assert_required_keys(options, [:path])
|
88
|
-
|
89
|
-
req_id = setup_call(:stat, options)
|
90
|
-
rc, stat = exists(req_id, options[:path], options[:callback], options[:watcher])
|
91
|
-
|
92
|
-
rv = { :req_id => req_id, :rc => rc }
|
93
|
-
options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
|
94
|
-
end
|
95
|
-
|
96
|
-
def create(options = {})
|
97
|
-
assert_open
|
98
|
-
assert_supported_keys(options, [:path, :data, :acl, :ephemeral, :sequence, :callback, :callback_context])
|
99
|
-
assert_required_keys(options, [:path])
|
100
|
-
assert_valid_data_size!(options[:data])
|
101
|
-
|
102
|
-
flags = 0
|
103
|
-
flags |= ZOO_EPHEMERAL if options[:ephemeral]
|
104
|
-
flags |= ZOO_SEQUENCE if options[:sequence]
|
105
|
-
|
106
|
-
options[:acl] ||= ZOO_OPEN_ACL_UNSAFE
|
107
|
-
|
108
|
-
req_id = setup_call(:create, options)
|
109
|
-
rc, newpath = super(req_id, options[:path], options[:data], options[:callback], options[:acl], flags)
|
110
|
-
|
111
|
-
rv = { :req_id => req_id, :rc => rc }
|
112
|
-
options[:callback] ? rv : rv.merge(:path => newpath)
|
113
|
-
end
|
114
|
-
|
115
|
-
def delete(options = {})
|
116
|
-
assert_open
|
117
|
-
assert_supported_keys(options, [:path, :version, :callback, :callback_context])
|
118
|
-
assert_required_keys(options, [:path])
|
119
|
-
options[:version] ||= -1
|
120
|
-
|
121
|
-
req_id = setup_call(:delete, options)
|
122
|
-
rc = super(req_id, options[:path], options[:version], options[:callback])
|
123
|
-
|
124
|
-
{ :req_id => req_id, :rc => rc }
|
125
|
-
end
|
126
|
-
|
127
|
-
# this method is *only* asynchronous
|
128
|
-
#
|
129
|
-
# @note There is a discrepancy between the zkc and java versions. zkc takes
|
130
|
-
# a string_callback_t, java takes a VoidCallback. You should most likely use
|
131
|
-
# the ZookeeperCallbacks::VoidCallback and not rely on the string value.
|
132
|
-
#
|
133
|
-
def sync(options = {})
|
134
|
-
assert_open
|
135
|
-
assert_supported_keys(options, [:path, :callback, :callback_context])
|
136
|
-
assert_required_keys(options, [:path, :callback])
|
137
|
-
|
138
|
-
req_id = setup_call(:sync, options)
|
139
|
-
|
140
|
-
rc = super(req_id, options[:path]) # we don't pass options[:callback] here as this method is *always* async
|
141
|
-
|
142
|
-
{ :req_id => req_id, :rc => rc }
|
143
|
-
end
|
144
|
-
|
145
|
-
def set_acl(options = {})
|
146
|
-
assert_open
|
147
|
-
assert_supported_keys(options, [:path, :acl, :version, :callback, :callback_context])
|
148
|
-
assert_required_keys(options, [:path, :acl])
|
149
|
-
options[:version] ||= -1
|
150
|
-
|
151
|
-
req_id = setup_call(:set_acl, options)
|
152
|
-
rc = super(req_id, options[:path], options[:acl], options[:callback], options[:version])
|
153
|
-
|
154
|
-
{ :req_id => req_id, :rc => rc }
|
155
|
-
end
|
156
|
-
|
157
|
-
def get_acl(options = {})
|
158
|
-
assert_open
|
159
|
-
assert_supported_keys(options, [:path, :callback, :callback_context])
|
160
|
-
assert_required_keys(options, [:path])
|
161
|
-
|
162
|
-
req_id = setup_call(:get_acl, options)
|
163
|
-
rc, acls, stat = super(req_id, options[:path], options[:callback])
|
164
|
-
|
165
|
-
rv = { :req_id => req_id, :rc => rc }
|
166
|
-
options[:callback] ? rv : rv.merge(:acl => acls, :stat => Stat.new(stat))
|
167
|
-
end
|
168
|
-
|
169
|
-
# close this client and any underyling connections
|
170
|
-
def close
|
171
|
-
super
|
172
|
-
end
|
173
|
-
|
174
|
-
def state
|
175
|
-
super
|
176
|
-
end
|
177
|
-
|
178
|
-
def connected?
|
179
|
-
super
|
41
|
+
# @private
|
42
|
+
def self.deprecation_warnings?
|
43
|
+
@deprecation_warnings = true if @deprecation_warnings.nil?
|
180
44
|
end
|
181
45
|
|
182
|
-
|
183
|
-
|
46
|
+
# set this to false to mute Zookeeper related deprecation warnings...
|
47
|
+
# __AT YOUR PERIL__
|
48
|
+
def self.deprecation_warnings=(v)
|
49
|
+
@deprecation_warnings = v
|
184
50
|
end
|
185
51
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
# There are some operations that are dangerous in the context of the event
|
191
|
-
# dispatch thread (because they would block further event delivery). This
|
192
|
-
# method allows clients to know if they're currently executing in the context of an
|
193
|
-
# event.
|
194
|
-
#
|
195
|
-
# @returns [true,false] true if the current thread is the event dispatch thread
|
196
|
-
def event_dispatch_thread?
|
197
|
-
super
|
52
|
+
# @private
|
53
|
+
def self.deprecation_warning(warning)
|
54
|
+
Kernel.warn(warning) if deprecation_warnings?
|
198
55
|
end
|
199
56
|
|
200
57
|
# for expert use only. set the underlying debug level for the C layer, has no
|
@@ -202,14 +59,14 @@ class Zookeeper < ZookeeperBase
|
|
202
59
|
#
|
203
60
|
# @private
|
204
61
|
def self.set_debug_level(val)
|
205
|
-
if defined?(
|
62
|
+
if defined?(CZookeeper)
|
206
63
|
CZookeeper.set_debug_level(val.to_i)
|
207
64
|
end
|
208
65
|
end
|
209
66
|
|
210
67
|
# @private
|
211
68
|
def self.get_debug_level
|
212
|
-
if defined?(
|
69
|
+
if defined?(CZookeeper)
|
213
70
|
CZookeeper.get_debug_level
|
214
71
|
end
|
215
72
|
end
|
@@ -221,77 +78,8 @@ class Zookeeper < ZookeeperBase
|
|
221
78
|
# @private
|
222
79
|
alias :debug_level :get_debug_level
|
223
80
|
end
|
224
|
-
|
225
|
-
# DEPRECATED: use the class-level method instead
|
226
|
-
def set_debug_level(val)
|
227
|
-
super
|
228
|
-
end
|
229
|
-
|
230
|
-
# has the underlying connection been closed?
|
231
|
-
def closed?
|
232
|
-
super
|
233
|
-
end
|
234
|
-
|
235
|
-
# is the event delivery system running?
|
236
|
-
def running?
|
237
|
-
super
|
238
|
-
end
|
239
|
-
|
240
|
-
# return the session id of the current connection as an Fixnum
|
241
|
-
def session_id
|
242
|
-
super
|
243
|
-
end
|
244
|
-
|
245
|
-
# Return the passwd portion of this connection's credentials as a String
|
246
|
-
def session_passwd
|
247
|
-
super
|
248
|
-
end
|
249
|
-
|
250
|
-
protected
|
251
|
-
# used during shutdown, awaken the event delivery thread if it's blocked
|
252
|
-
# waiting for the next event
|
253
|
-
def wake_event_loop!
|
254
|
-
super
|
255
|
-
end
|
256
|
-
|
257
|
-
# starts the event delivery subsystem going. after calling this method, running? will be true
|
258
|
-
def setup_dispatch_thread!
|
259
|
-
super
|
260
|
-
end
|
261
|
-
|
262
|
-
# TODO: describe what this does
|
263
|
-
def get_default_global_watcher
|
264
|
-
super
|
265
|
-
end
|
266
|
-
|
267
|
-
def logger
|
268
|
-
Zookeeper.logger
|
269
|
-
end
|
270
|
-
|
271
|
-
def assert_valid_data_size!(data)
|
272
|
-
return if data.nil?
|
273
|
-
|
274
|
-
data = data.to_s
|
275
|
-
if data.length >= 1048576 # one megabyte
|
276
|
-
raise ZookeeperException::DataTooLargeException, "data must be smaller than 1 MiB, your data starts with: #{data[0..32].inspect}"
|
277
|
-
end
|
278
|
-
nil
|
279
|
-
end
|
280
|
-
|
281
|
-
private
|
282
|
-
# TODO: Sanitize user mistakes by unregistering watchers from ops that
|
283
|
-
# don't return ZOK (except wexists)? Make users clean up after themselves for now.
|
284
|
-
#
|
285
|
-
# XXX: is this dead code?
|
286
|
-
def unregister_watcher(req_id)
|
287
|
-
@mutex.synchronize {
|
288
|
-
@watcher_reqs.delete(req_id)
|
289
|
-
}
|
290
|
-
end
|
291
|
-
|
292
|
-
# must be supplied by parent class impl.
|
293
|
-
def assert_open
|
294
|
-
super
|
295
|
-
end
|
296
81
|
end
|
297
82
|
|
83
|
+
# just for first test, get rid of this soon
|
84
|
+
require_relative 'zookeeper/compatibility'
|
85
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
if ARGV.empty?
|
4
|
+
$stderr.puts <<-EOS
|
5
|
+
Usage: #{File.basename(__FILE__)} file1 file2 file3
|
6
|
+
|
7
|
+
Fix references to Zookeeper classes and modules.
|
8
|
+
|
9
|
+
This script acts like sed and edits files in place (not saving backups,
|
10
|
+
as you *are* using source control and aren't a complete tool).
|
11
|
+
|
12
|
+
if you have any doubts, *read the script*:
|
13
|
+
----------------------------------------------------------------------
|
14
|
+
|
15
|
+
#{File.read(__FILE__)}
|
16
|
+
|
17
|
+
EOS
|
18
|
+
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
require 'tempfile'
|
24
|
+
require 'fileutils'
|
25
|
+
|
26
|
+
ARGV.each do |path|
|
27
|
+
Tempfile.open(File.basename(path)) do |tmp|
|
28
|
+
File.open(path) do |input|
|
29
|
+
while line = input.gets
|
30
|
+
tmp.puts line.gsub(/\bZookeeperStat::Stat\b/, 'Zookeeper::Stat').
|
31
|
+
gsub(/\bZookeeper::(\w+)Callback\b/, 'Zookeeper::Callbacks::\1Callback').
|
32
|
+
gsub(/\bZookeeperACLs::(ZOO_\w+)\b/, 'Zookeeper::Constants::\1').
|
33
|
+
gsub(/\bZookeeperExceptions::ZookeeperException::(\w+)\b/, 'Zookeeper::Exceptions::\1').
|
34
|
+
gsub(/\bZookeeper(Constants|Exceptions|Common|ACLs|Callbacks)\b/, 'Zookeeper::\1').
|
35
|
+
gsub(/\bZookeeperException::(\w+)\b/, 'Exceptions::\1')
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
tmp.fsync
|
41
|
+
tmp.close
|
42
|
+
|
43
|
+
FileUtils.mv(tmp.path, path)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/spec/c_zookeeper_spec.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# tests the CZookeeper, obviously only available when running under MRI
|
2
|
-
require 'spec_helper'
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
unless defined?(::JRUBY_VERSION)
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
describe Zookeeper::CZookeeper do
|
6
7
|
def pop_all_events
|
7
8
|
[].tap do |rv|
|
8
9
|
begin
|
@@ -13,13 +14,13 @@ if Module.const_defined?(:CZookeeper)
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def wait_until_connected(timeout=2)
|
16
|
-
wait_until(timeout) { @czk.state ==
|
17
|
+
wait_until(timeout) { @czk.state == Zookeeper::Constants::ZOO_CONNECTED_STATE }
|
17
18
|
end
|
18
19
|
|
19
20
|
describe do
|
20
21
|
before do
|
21
|
-
@event_queue =
|
22
|
-
@czk = CZookeeper.new(
|
22
|
+
@event_queue = Zookeeper::Common::QueueWithPipe.new
|
23
|
+
@czk = Zookeeper::CZookeeper.new(Zookeeper.default_cnx_str, @event_queue)
|
23
24
|
end
|
24
25
|
|
25
26
|
after do
|
@@ -39,9 +40,9 @@ if Module.const_defined?(:CZookeeper)
|
|
39
40
|
it %[should have a connection event after being connected] do
|
40
41
|
event = wait_until(2) { @event_queue.pop }
|
41
42
|
event.should be
|
42
|
-
event[:req_id].should ==
|
43
|
-
event[:type].should ==
|
44
|
-
event[:state].should ==
|
43
|
+
event[:req_id].should == Zookeeper::Common::ZKRB_GLOBAL_CB_REQ
|
44
|
+
event[:type].should == Zookeeper::Constants::ZOO_SESSION_EVENT
|
45
|
+
event[:state].should == Zookeeper::Constants::ZOO_CONNECTED_STATE
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
@@ -6,7 +6,7 @@ describe 'Zookeeper chrooted' do
|
|
6
6
|
let(:data) { "underpants" }
|
7
7
|
let(:chroot_path) { '/slyphon-zookeeper-chroot' }
|
8
8
|
|
9
|
-
let(:connection_string) { "
|
9
|
+
let(:connection_string) { "#{Zookeeper.default_cnx_str}#{chroot_path}" }
|
10
10
|
|
11
11
|
before do
|
12
12
|
@zk = Zookeeper.new(connection_string)
|
@@ -52,7 +52,7 @@ describe 'Zookeeper chrooted' do
|
|
52
52
|
it %[should return ZNONODE] do
|
53
53
|
rv = zk.create(:path => '/', :data => '')
|
54
54
|
rv[:rc].should_not be_zero
|
55
|
-
rv[:rc].should ==
|
55
|
+
rv[:rc].should == Zookeeper::Exceptions::ZNONODE
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -5,18 +5,18 @@ describe Zookeeper do
|
|
5
5
|
before do
|
6
6
|
@events = []
|
7
7
|
@watch_block = lambda do |hash|
|
8
|
-
|
8
|
+
logger.debug "watch_block: #{hash.inspect}"
|
9
9
|
@events << hash
|
10
10
|
end
|
11
11
|
|
12
|
-
@zk = Zookeeper.new(
|
12
|
+
@zk = Zookeeper.new(Zookeeper.default_cnx_str, 10, @watch_block)
|
13
13
|
|
14
14
|
wait_until(2) { @zk.connected? }
|
15
15
|
@zk.should be_connected
|
16
|
-
|
16
|
+
logger.debug "connected!"
|
17
17
|
|
18
18
|
wait_until(2) { !@events.empty? }
|
19
|
-
|
19
|
+
logger.debug "got events!"
|
20
20
|
end
|
21
21
|
|
22
22
|
after do
|