zookeeper-ng 1.5.2.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.
- checksums.yaml +7 -0
- data/.ctags_paths +1 -0
- data/.dotfiles/ruby-gemset +1 -0
- data/.dotfiles/ruby-version +1 -0
- data/.dotfiles/rvmrc +2 -0
- data/.github/workflows/build.yml +57 -0
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/CHANGELOG +408 -0
- data/Gemfile +30 -0
- data/Guardfile +8 -0
- data/LICENSE +23 -0
- data/Manifest +29 -0
- data/README.markdown +62 -0
- data/Rakefile +121 -0
- data/cause-abort.rb +117 -0
- data/ext/.gitignore +6 -0
- data/ext/Rakefile +41 -0
- data/ext/c_zookeeper.rb +398 -0
- data/ext/common.h +17 -0
- data/ext/dbg.h +53 -0
- data/ext/depend +5 -0
- data/ext/event_lib.c +740 -0
- data/ext/event_lib.h +175 -0
- data/ext/extconf.rb +103 -0
- data/ext/generate_gvl_code.rb +321 -0
- data/ext/patches/zkc-3.3.5-network.patch +24 -0
- data/ext/patches/zkc-3.4.5-buffer-overflow.patch +11 -0
- data/ext/patches/zkc-3.4.5-config.patch +5454 -0
- data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
- data/ext/patches/zkc-3.4.5-logging.patch +41 -0
- data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
- data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
- data/ext/zkc-3.4.5.tar.gz +0 -0
- data/ext/zkrb.c +1080 -0
- data/ext/zkrb_wrapper.c +775 -0
- data/ext/zkrb_wrapper.h +350 -0
- data/ext/zkrb_wrapper_compat.c +15 -0
- data/ext/zkrb_wrapper_compat.h +11 -0
- data/ext/zookeeper_base.rb +256 -0
- data/java/java_base.rb +501 -0
- data/lib/zookeeper/acls.rb +44 -0
- data/lib/zookeeper/callbacks.rb +108 -0
- data/lib/zookeeper/client.rb +30 -0
- data/lib/zookeeper/client_methods.rb +282 -0
- data/lib/zookeeper/common/queue_with_pipe.rb +110 -0
- data/lib/zookeeper/common.rb +122 -0
- data/lib/zookeeper/compatibility.rb +138 -0
- data/lib/zookeeper/constants.rb +97 -0
- data/lib/zookeeper/continuation.rb +223 -0
- data/lib/zookeeper/core_ext.rb +58 -0
- data/lib/zookeeper/em_client.rb +55 -0
- data/lib/zookeeper/exceptions.rb +135 -0
- data/lib/zookeeper/forked.rb +19 -0
- data/lib/zookeeper/latch.rb +34 -0
- data/lib/zookeeper/logger/forwarding_logger.rb +84 -0
- data/lib/zookeeper/logger.rb +39 -0
- data/lib/zookeeper/monitor.rb +19 -0
- data/lib/zookeeper/rake_tasks.rb +165 -0
- data/lib/zookeeper/request_registry.rb +153 -0
- data/lib/zookeeper/stat.rb +21 -0
- data/lib/zookeeper/version.rb +4 -0
- data/lib/zookeeper.rb +115 -0
- data/notes.txt +14 -0
- data/scripts/upgrade-1.0-sed-alike.rb +46 -0
- data/spec/c_zookeeper_spec.rb +51 -0
- data/spec/chrooted_connection_spec.rb +83 -0
- data/spec/compatibilty_spec.rb +8 -0
- data/spec/default_watcher_spec.rb +41 -0
- data/spec/em_spec.rb +51 -0
- data/spec/ext/zookeeper_base_spec.rb +19 -0
- data/spec/forked_connection_spec.rb +122 -0
- data/spec/latch_spec.rb +24 -0
- data/spec/log4j.properties +17 -0
- data/spec/shared/all_success_return_values.rb +10 -0
- data/spec/shared/connection_examples.rb +1081 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/00_logging.rb +38 -0
- data/spec/support/10_spawn_zookeeper.rb +20 -0
- data/spec/support/progress_formatter.rb +15 -0
- data/spec/support/zookeeper_spec_helpers.rb +96 -0
- data/spec/zookeeper_spec.rb +24 -0
- data/zookeeper.gemspec +46 -0
- data/zoomonkey/duplicates +3 -0
- data/zoomonkey/zoomonkey.rb +194 -0
- metadata +185 -0
@@ -0,0 +1,282 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module ClientMethods
|
3
|
+
extend Forwardable
|
4
|
+
include Constants
|
5
|
+
include ACLs
|
6
|
+
include Logger
|
7
|
+
|
8
|
+
# @req_registry is set up in the platform-specific base classes
|
9
|
+
def_delegators :@req_registry, :setup_call
|
10
|
+
private :setup_call
|
11
|
+
|
12
|
+
def reopen(timeout=10, watcher=nil, opts = {})
|
13
|
+
warn "WARN: ZookeeperBase#reopen watcher argument is now ignored" if watcher
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(host, timeout=10, watcher=nil, opts = {})
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_auth(options = {})
|
22
|
+
assert_open
|
23
|
+
assert_keys(options,
|
24
|
+
:supported => [:scheme, :cert],
|
25
|
+
:required => [:scheme, :cert])
|
26
|
+
|
27
|
+
req_id = setup_call(:add_auth, options)
|
28
|
+
rc = super(req_id, options[:scheme], options[:cert])
|
29
|
+
|
30
|
+
{ :req_id => req_id, :rc => rc }
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(options = {})
|
34
|
+
assert_open
|
35
|
+
assert_keys(options,
|
36
|
+
:supported => [:path, :watcher, :watcher_context, :callback, :callback_context],
|
37
|
+
:required => [:path])
|
38
|
+
|
39
|
+
req_id = setup_call(:get, options)
|
40
|
+
rc, value, stat = super(req_id, options[:path], options[:callback], options[:watcher])
|
41
|
+
|
42
|
+
rv = { :req_id => req_id, :rc => rc }
|
43
|
+
options[:callback] ? rv : rv.merge(:data => value, :stat => Stat.new(stat))
|
44
|
+
end
|
45
|
+
|
46
|
+
def set(options = {})
|
47
|
+
assert_open
|
48
|
+
assert_keys(options,
|
49
|
+
:supported => [:path, :data, :version, :callback, :callback_context],
|
50
|
+
:required => [:path])
|
51
|
+
|
52
|
+
assert_valid_data_size!(options[:data])
|
53
|
+
options[:version] ||= -1
|
54
|
+
|
55
|
+
req_id = setup_call(:set, options)
|
56
|
+
rc, stat = super(req_id, options[:path], options[:data], options[:callback], options[:version])
|
57
|
+
|
58
|
+
rv = { :req_id => req_id, :rc => rc }
|
59
|
+
options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_children(options = {})
|
63
|
+
assert_open
|
64
|
+
assert_keys(options,
|
65
|
+
:supported => [:path, :callback, :callback_context, :watcher, :watcher_context],
|
66
|
+
:required => [:path])
|
67
|
+
|
68
|
+
req_id = setup_call(:get_children, options)
|
69
|
+
rc, children, stat = super(req_id, options[:path], options[:callback], options[:watcher])
|
70
|
+
|
71
|
+
rv = { :req_id => req_id, :rc => rc }
|
72
|
+
options[:callback] ? rv : rv.merge(:children => children, :stat => Stat.new(stat))
|
73
|
+
end
|
74
|
+
|
75
|
+
def stat(options = {})
|
76
|
+
assert_open
|
77
|
+
assert_keys(options,
|
78
|
+
:supported => [:path, :callback, :callback_context, :watcher, :watcher_context],
|
79
|
+
:required => [:path])
|
80
|
+
|
81
|
+
req_id = setup_call(:stat, options)
|
82
|
+
rc, stat = exists(req_id, options[:path], options[:callback], options[:watcher])
|
83
|
+
|
84
|
+
rv = { :req_id => req_id, :rc => rc }
|
85
|
+
options[:callback] ? rv : rv.merge(:stat => Stat.new(stat))
|
86
|
+
end
|
87
|
+
|
88
|
+
def create(options = {})
|
89
|
+
assert_open
|
90
|
+
assert_keys(options,
|
91
|
+
:supported => [:path, :data, :acl, :ephemeral, :sequence, :callback, :callback_context],
|
92
|
+
:required => [:path])
|
93
|
+
|
94
|
+
assert_valid_data_size!(options[:data])
|
95
|
+
|
96
|
+
flags = 0
|
97
|
+
flags |= ZOO_EPHEMERAL if options[:ephemeral]
|
98
|
+
flags |= ZOO_SEQUENCE if options[:sequence]
|
99
|
+
|
100
|
+
options[:acl] ||= ZOO_OPEN_ACL_UNSAFE
|
101
|
+
|
102
|
+
req_id = setup_call(:create, options)
|
103
|
+
rc, newpath = super(req_id, options[:path], options[:data], options[:callback], options[:acl], flags)
|
104
|
+
|
105
|
+
rv = { :req_id => req_id, :rc => rc }
|
106
|
+
options[:callback] ? rv : rv.merge(:path => newpath)
|
107
|
+
end
|
108
|
+
|
109
|
+
def delete(options = {})
|
110
|
+
assert_open
|
111
|
+
assert_keys(options,
|
112
|
+
:supported => [:path, :version, :callback, :callback_context],
|
113
|
+
:required => [:path])
|
114
|
+
|
115
|
+
options[:version] ||= -1
|
116
|
+
|
117
|
+
req_id = setup_call(:delete, options)
|
118
|
+
rc = super(req_id, options[:path], options[:version], options[:callback])
|
119
|
+
|
120
|
+
{ :req_id => req_id, :rc => rc }
|
121
|
+
end
|
122
|
+
|
123
|
+
# this method is *only* asynchronous
|
124
|
+
#
|
125
|
+
# @note There is a discrepancy between the zkc and java versions. zkc takes
|
126
|
+
# a string_callback_t, java takes a VoidCallback. You should most likely use
|
127
|
+
# the Zookeeper::Callbacks::VoidCallback and not rely on the string value.
|
128
|
+
#
|
129
|
+
def sync(options = {})
|
130
|
+
assert_open
|
131
|
+
assert_keys(options,
|
132
|
+
:supported => [:path, :callback, :callback_context],
|
133
|
+
:required => [:path, :callback])
|
134
|
+
|
135
|
+
req_id = setup_call(:sync, options)
|
136
|
+
|
137
|
+
rc = super(req_id, options[:path]) # we don't pass options[:callback] here as this method is *always* async
|
138
|
+
|
139
|
+
{ :req_id => req_id, :rc => rc }
|
140
|
+
end
|
141
|
+
|
142
|
+
def set_acl(options = {})
|
143
|
+
assert_open
|
144
|
+
assert_keys(options,
|
145
|
+
:supported => [:path, :acl, :version, :callback, :callback_context],
|
146
|
+
:required => [:path, :acl])
|
147
|
+
options[:version] ||= -1
|
148
|
+
|
149
|
+
req_id = setup_call(:set_acl, options)
|
150
|
+
rc = super(req_id, options[:path], options[:acl], options[:callback], options[:version])
|
151
|
+
|
152
|
+
{ :req_id => req_id, :rc => rc }
|
153
|
+
end
|
154
|
+
|
155
|
+
def get_acl(options = {})
|
156
|
+
assert_open
|
157
|
+
assert_keys(options,
|
158
|
+
:supported => [:path, :callback, :callback_context],
|
159
|
+
:required => [:path])
|
160
|
+
|
161
|
+
req_id = setup_call(:get_acl, options)
|
162
|
+
rc, acls, stat = super(req_id, options[:path], options[:callback])
|
163
|
+
|
164
|
+
rv = { :req_id => req_id, :rc => rc }
|
165
|
+
options[:callback] ? rv : rv.merge(:acl => acls, :stat => Stat.new(stat))
|
166
|
+
end
|
167
|
+
|
168
|
+
# close this client and any underlying connections
|
169
|
+
def close
|
170
|
+
super
|
171
|
+
end
|
172
|
+
|
173
|
+
def state
|
174
|
+
super
|
175
|
+
end
|
176
|
+
|
177
|
+
def connected?
|
178
|
+
super
|
179
|
+
end
|
180
|
+
|
181
|
+
def connecting?
|
182
|
+
super
|
183
|
+
end
|
184
|
+
|
185
|
+
def associating?
|
186
|
+
super
|
187
|
+
end
|
188
|
+
|
189
|
+
# There are some operations that are dangerous in the context of the event
|
190
|
+
# dispatch thread (because they would block further event delivery). This
|
191
|
+
# method allows clients to know if they're currently executing in the context of an
|
192
|
+
# event.
|
193
|
+
#
|
194
|
+
# @returns [true,false] true if the current thread is the event dispatch thread
|
195
|
+
def event_dispatch_thread?
|
196
|
+
super
|
197
|
+
end
|
198
|
+
|
199
|
+
# DEPRECATED: use the class-level method instead
|
200
|
+
def set_debug_level(val)
|
201
|
+
super
|
202
|
+
end
|
203
|
+
|
204
|
+
# has the underlying connection been closed?
|
205
|
+
def closed?
|
206
|
+
super
|
207
|
+
end
|
208
|
+
|
209
|
+
# is the event delivery system running?
|
210
|
+
def running?
|
211
|
+
super
|
212
|
+
end
|
213
|
+
|
214
|
+
# return the session id of the current connection as an Fixnum
|
215
|
+
def session_id
|
216
|
+
super
|
217
|
+
end
|
218
|
+
|
219
|
+
# Return the passwd portion of this connection's credentials as a String
|
220
|
+
def session_passwd
|
221
|
+
super
|
222
|
+
end
|
223
|
+
|
224
|
+
# stop all underlying threads in preparation for a fork()
|
225
|
+
def pause_before_fork_in_parent
|
226
|
+
super
|
227
|
+
end
|
228
|
+
|
229
|
+
# re-start all underlying threads after performing a fork()
|
230
|
+
def resume_after_fork_in_parent
|
231
|
+
super
|
232
|
+
end
|
233
|
+
|
234
|
+
protected
|
235
|
+
# used during shutdown, awaken the event delivery thread if it's blocked
|
236
|
+
# waiting for the next event
|
237
|
+
def wake_event_loop!
|
238
|
+
super
|
239
|
+
end
|
240
|
+
|
241
|
+
# starts the event delivery subsystem going. after calling this method, running? will be true
|
242
|
+
def setup_dispatch_thread!
|
243
|
+
super
|
244
|
+
end
|
245
|
+
|
246
|
+
# TODO: describe what this does
|
247
|
+
def get_default_global_watcher
|
248
|
+
super
|
249
|
+
end
|
250
|
+
|
251
|
+
def assert_valid_data_size!(data)
|
252
|
+
return if data.nil?
|
253
|
+
|
254
|
+
data = data.to_s
|
255
|
+
if data.length >= 1048576 # one megabyte
|
256
|
+
raise Zookeeper::Exceptions::DataTooLargeException, "data must be smaller than 1 MiB, your data starts with: #{data[0..32].inspect}"
|
257
|
+
end
|
258
|
+
nil
|
259
|
+
end
|
260
|
+
|
261
|
+
private
|
262
|
+
def assert_keys(args, opts={})
|
263
|
+
supported = opts[:supported] || []
|
264
|
+
required = opts[:required] || []
|
265
|
+
|
266
|
+
unless (args.keys - supported).empty?
|
267
|
+
raise Zookeeper::Exceptions::BadArguments,
|
268
|
+
"Supported arguments are: #{supported.inspect}, but arguments #{args.keys.inspect} were supplied instead"
|
269
|
+
end
|
270
|
+
|
271
|
+
unless (required - args.keys).empty?
|
272
|
+
raise Zookeeper::Exceptions::BadArguments,
|
273
|
+
"Required arguments are: #{required.inspect}, but only the arguments #{args.keys.inspect} were supplied."
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# must be supplied by parent class impl.
|
278
|
+
def assert_open
|
279
|
+
super
|
280
|
+
end
|
281
|
+
end # ClientMethods
|
282
|
+
end # Zookeeper
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Common
|
3
|
+
# Ceci n'est pas une pipe
|
4
|
+
class QueueWithPipe
|
5
|
+
extend Forwardable
|
6
|
+
include Logger
|
7
|
+
|
8
|
+
# raised when close has been called, and pop() is performed
|
9
|
+
#
|
10
|
+
class ShutdownException < StandardError; end
|
11
|
+
|
12
|
+
# @private
|
13
|
+
KILL_TOKEN = Object.new unless defined?(KILL_TOKEN)
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@array = []
|
17
|
+
|
18
|
+
@mutex = Mutex.new
|
19
|
+
@cond = ConditionVariable.new
|
20
|
+
@closed = false
|
21
|
+
@graceful = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear
|
25
|
+
@mutex.lock
|
26
|
+
begin
|
27
|
+
@array.clear
|
28
|
+
ensure
|
29
|
+
@mutex.unlock rescue nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def push(obj)
|
34
|
+
@mutex.lock
|
35
|
+
begin
|
36
|
+
# raise ShutdownException if (@closed or @graceful)
|
37
|
+
@array << obj
|
38
|
+
@cond.signal
|
39
|
+
ensure
|
40
|
+
@mutex.unlock rescue nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def pop(non_blocking=false)
|
45
|
+
rval = nil
|
46
|
+
|
47
|
+
@mutex.lock
|
48
|
+
begin
|
49
|
+
|
50
|
+
begin
|
51
|
+
raise ShutdownException if @closed # this may get us in trouble
|
52
|
+
|
53
|
+
rval = @array.shift
|
54
|
+
|
55
|
+
unless rval
|
56
|
+
raise ThreadError if non_blocking # sigh, ruby's stupid behavior
|
57
|
+
raise ShutdownException if @graceful # we've processed all the remaining mesages
|
58
|
+
|
59
|
+
@cond.wait(@mutex) until (@closed or @graceful or (@array.length > 0))
|
60
|
+
end
|
61
|
+
end until rval
|
62
|
+
|
63
|
+
return rval
|
64
|
+
|
65
|
+
ensure
|
66
|
+
@mutex.unlock rescue nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# close the queue and causes ShutdownException to be raised on waiting threads
|
71
|
+
def graceful_close!
|
72
|
+
@mutex.lock
|
73
|
+
begin
|
74
|
+
return if @graceful or @closed
|
75
|
+
logger.debug { "#{self.class}##{__method__} gracefully closing" }
|
76
|
+
@graceful = true
|
77
|
+
@cond.broadcast
|
78
|
+
ensure
|
79
|
+
@mutex.unlock rescue nil
|
80
|
+
end
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def open
|
85
|
+
@mutex.lock
|
86
|
+
begin
|
87
|
+
@closed = @graceful = false
|
88
|
+
@cond.broadcast
|
89
|
+
ensure
|
90
|
+
@mutex.unlock rescue nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def close
|
95
|
+
@mutex.lock
|
96
|
+
begin
|
97
|
+
return if @closed
|
98
|
+
@closed = true
|
99
|
+
@cond.broadcast
|
100
|
+
ensure
|
101
|
+
@mutex.unlock rescue nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def closed?
|
106
|
+
@mutex.synchronize { !!@closed }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'zookeeper/exceptions'
|
2
|
+
require 'zookeeper/common/queue_with_pipe'
|
3
|
+
|
4
|
+
module Zookeeper
|
5
|
+
module Common
|
6
|
+
def event_dispatch_thread?
|
7
|
+
@dispatcher && (@dispatcher == Thread.current)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def setup_dispatch_thread!
|
12
|
+
@mutex.synchronize do
|
13
|
+
if @dispatcher
|
14
|
+
logger.debug { "dispatcher already running" }
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
logger.debug { "starting dispatch thread" }
|
19
|
+
|
20
|
+
@dispatcher = Thread.new(&method(:dispatch_thread_body))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# this method is part of the reopen/close code, and is responsible for
|
25
|
+
# shutting down the dispatch thread.
|
26
|
+
#
|
27
|
+
# @dispatcher will be nil when this method exits
|
28
|
+
#
|
29
|
+
def stop_dispatch_thread!(timeout=2)
|
30
|
+
logger.debug { "#{self.class}##{__method__}" }
|
31
|
+
|
32
|
+
if @dispatcher
|
33
|
+
if @dispatcher.join(0)
|
34
|
+
@dispatcher = nil
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
@mutex.synchronize do
|
39
|
+
event_queue.graceful_close!
|
40
|
+
|
41
|
+
# we now release the mutex so that dispatch_next_callback can grab it
|
42
|
+
# to do what it needs to do while delivering events
|
43
|
+
#
|
44
|
+
@dispatch_shutdown_cond.wait
|
45
|
+
|
46
|
+
# wait for another timeout sec for the thread to join
|
47
|
+
until @dispatcher.join(timeout)
|
48
|
+
logger.error { "Dispatch thread did not join cleanly, waiting" }
|
49
|
+
end
|
50
|
+
@dispatcher = nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_next_event(blocking=true)
|
56
|
+
@event_queue.pop(!blocking).tap do |event|
|
57
|
+
logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
|
58
|
+
end
|
59
|
+
rescue ThreadError
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def dispatch_next_callback(hash)
|
64
|
+
return nil unless hash
|
65
|
+
|
66
|
+
logger.debug { "get_next_event returned: #{prettify_event(hash).inspect}" }
|
67
|
+
|
68
|
+
is_completion = hash.has_key?(:rc)
|
69
|
+
|
70
|
+
hash[:stat] = Zookeeper::Stat.new(hash[:stat]) if hash.has_key?(:stat)
|
71
|
+
hash[:acl] = hash[:acl].map { |acl| Zookeeper::ACLs::ACL.new(acl) } if hash[:acl]
|
72
|
+
|
73
|
+
callback_context = @req_registry.get_context_for(hash)
|
74
|
+
|
75
|
+
if callback_context
|
76
|
+
callback = is_completion ? callback_context[:callback] : callback_context[:watcher]
|
77
|
+
|
78
|
+
hash[:context] = callback_context[:context]
|
79
|
+
|
80
|
+
if callback.respond_to?(:call)
|
81
|
+
callback.call(hash)
|
82
|
+
else
|
83
|
+
# puts "dispatch_next_callback found non-callback => #{callback.inspect}"
|
84
|
+
end
|
85
|
+
else
|
86
|
+
logger.warn { "Duplicate event received (no handler for req_id #{hash[:req_id]}, event: #{hash.inspect}" }
|
87
|
+
end
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def dispatch_thread_body
|
92
|
+
while true
|
93
|
+
begin
|
94
|
+
dispatch_next_callback(get_next_event(true))
|
95
|
+
rescue QueueWithPipe::ShutdownException
|
96
|
+
logger.info { "dispatch thread exiting, got shutdown exception" }
|
97
|
+
return
|
98
|
+
rescue Exception => e
|
99
|
+
$stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
ensure
|
103
|
+
signal_dispatch_thread_exit!
|
104
|
+
end
|
105
|
+
|
106
|
+
def signal_dispatch_thread_exit!
|
107
|
+
@mutex.synchronize do
|
108
|
+
logger.debug { "dispatch thread exiting!" }
|
109
|
+
@dispatch_shutdown_cond.broadcast
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def prettify_event(hash)
|
114
|
+
hash.dup.tap do |h|
|
115
|
+
# pretty up the event display
|
116
|
+
h[:type] = Zookeeper::Constants::EVENT_TYPE_NAMES.fetch(h[:type]) if h[:type]
|
117
|
+
h[:state] = Zookeeper::Constants::STATE_NAMES.fetch(h[:state]) if h[:state]
|
118
|
+
h[:req_id] = :global_session if h[:req_id] == -1
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
# @private
|
3
|
+
def self.warn_about_compatability_once!
|
4
|
+
return if @warned_about_compatibility
|
5
|
+
@warned_about_compatibility = true
|
6
|
+
|
7
|
+
warn <<-EOS
|
8
|
+
|
9
|
+
-----------------------------------------------------------------------------
|
10
|
+
|
11
|
+
NOTICE: ZOOKEEPER BACKWARDS COMPATIBILTY EANBLED!!
|
12
|
+
|
13
|
+
THIS WILL NOT BE AUTOMATIC IN 1.1 !!
|
14
|
+
|
15
|
+
There was a major change to the organization of the Zookeeper gem between
|
16
|
+
0.9 and 1.0, breaking backwards compatibility. To ease the transition,
|
17
|
+
|
18
|
+
#{__FILE__}
|
19
|
+
|
20
|
+
is automatically required. This will *not* be the case in 1.1.
|
21
|
+
|
22
|
+
-----------------------------------------------------------------------------
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.warned_about_compatability?
|
27
|
+
!!@warned_about_compatability
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# at request of @eric
|
32
|
+
#Zookeeper.warn_about_compatability_once!
|
33
|
+
|
34
|
+
module Zookeeper
|
35
|
+
module Compatibility
|
36
|
+
def clean_backtrace
|
37
|
+
caller[0..-2].reject {|n| n =~ %r%/rspec/|\(eval\)|const_missing% }.map { |n| "\t#{n}" }.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module ZookeeperConstants
|
43
|
+
include Zookeeper::Constants
|
44
|
+
end
|
45
|
+
|
46
|
+
module ZookeeperCallbacks
|
47
|
+
include Zookeeper::Callbacks
|
48
|
+
Callback = Base
|
49
|
+
end
|
50
|
+
|
51
|
+
module ZookeeperExceptions
|
52
|
+
include Zookeeper::Exceptions
|
53
|
+
end
|
54
|
+
|
55
|
+
module ZookeeperStat
|
56
|
+
extend Zookeeper::Compatibility
|
57
|
+
def self.const_missing(sym)
|
58
|
+
if sym == :Stat
|
59
|
+
warn "\nZookeeperStat::Stat is now Zookeeper::Stat, please update your code!\n#{clean_backtrace}"
|
60
|
+
# self.const_set(sym, Zookeeper::Stat)
|
61
|
+
Zookeeper::Stat
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module ZookeeperACLs
|
69
|
+
extend Zookeeper::Compatibility
|
70
|
+
def self.const_missing(sym)
|
71
|
+
candidates = [Zookeeper::ACLs, Zookeeper::Constants, Zookeeper::ACLs::Constants]
|
72
|
+
|
73
|
+
candidates.each do |candidate|
|
74
|
+
if candidate.const_defined?(sym)
|
75
|
+
warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
|
76
|
+
|
77
|
+
c = candidate.const_get(sym)
|
78
|
+
# self.const_set(sym, c)
|
79
|
+
return c
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
module ZookeeperCommon
|
88
|
+
include Zookeeper::Common
|
89
|
+
extend Zookeeper::Compatibility
|
90
|
+
|
91
|
+
def self.const_missing(sym)
|
92
|
+
candidate = Zookeeper::Common
|
93
|
+
|
94
|
+
if candidate.const_defined?(sym)
|
95
|
+
warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
|
96
|
+
|
97
|
+
candidate.const_get(sym).tap do |c|
|
98
|
+
# self.const_set(sym, c)
|
99
|
+
end
|
100
|
+
else
|
101
|
+
super
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
# module Zookeeper
|
108
|
+
# include ZookeeperConstants
|
109
|
+
# include ZookeeperCallbacks
|
110
|
+
# include ZookeeperExceptions
|
111
|
+
# include ZookeeperCommon
|
112
|
+
# include ZookeeperStat
|
113
|
+
# include ZookeeperACLs
|
114
|
+
# end
|
115
|
+
|
116
|
+
module Zookeeper
|
117
|
+
extend Zookeeper::Compatibility
|
118
|
+
def self.const_missing(sym)
|
119
|
+
candidate =
|
120
|
+
case sym.to_s
|
121
|
+
when /Callback/
|
122
|
+
Zookeeper::Callbacks
|
123
|
+
end
|
124
|
+
|
125
|
+
super unless candidate
|
126
|
+
|
127
|
+
if candidate.const_defined?(sym)
|
128
|
+
warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
|
129
|
+
|
130
|
+
candidate.const_get(sym).tap do |c|
|
131
|
+
# self.const_set(sym, c)
|
132
|
+
end
|
133
|
+
else
|
134
|
+
super
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|