slyphon-zookeeper 0.3.0-java → 0.8.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +34 -0
- data/Rakefile +25 -5
- data/ext/c_zookeeper.rb +214 -0
- data/ext/dbg.h +18 -2
- data/ext/depend +1 -2
- data/ext/zookeeper_base.rb +73 -99
- data/ext/zookeeper_c.c +52 -41
- data/ext/zookeeper_lib.c +90 -78
- data/ext/zookeeper_lib.h +0 -1
- data/java/zookeeper_base.rb +72 -154
- data/lib/zookeeper/common/queue_with_pipe.rb +78 -0
- data/lib/zookeeper/common.rb +73 -9
- data/lib/zookeeper/constants.rb +28 -0
- data/lib/zookeeper/em_client.rb +13 -138
- data/lib/zookeeper/exceptions.rb +4 -1
- data/lib/zookeeper.rb +51 -15
- data/slyphon-zookeeper.gemspec +1 -1
- data/spec/c_zookeeper_spec.rb +50 -0
- data/spec/chrooted_connection_spec.rb +121 -0
- data/spec/em_spec.rb +0 -61
- data/spec/shared/all_success_return_values.rb +10 -0
- data/spec/shared/connection_examples.rb +1007 -0
- data/spec/spec_helper.rb +42 -19
- data/spec/zookeeper_spec.rb +8 -1033
- metadata +16 -6
data/java/zookeeper_base.rb
CHANGED
@@ -59,53 +59,6 @@ class ZookeeperBase
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
class QueueWithPipe
|
63
|
-
attr_writer :clear_reads_on_pop
|
64
|
-
|
65
|
-
def initialize
|
66
|
-
r, w = IO.pipe
|
67
|
-
@pipe = { :read => r, :write => w }
|
68
|
-
@queue = Queue.new
|
69
|
-
|
70
|
-
# with the EventMachine client, we want to let EM handle clearing the
|
71
|
-
# event pipe, so we set this to false
|
72
|
-
@clear_reads_on_pop = true
|
73
|
-
end
|
74
|
-
|
75
|
-
def push(obj)
|
76
|
-
rv = @queue.push(obj)
|
77
|
-
@pipe[:write].write('0')
|
78
|
-
logger.debug { "pushed #{obj.inspect} onto queue and wrote to pipe" }
|
79
|
-
rv
|
80
|
-
end
|
81
|
-
|
82
|
-
def pop(non_blocking=false)
|
83
|
-
rv = @queue.pop(non_blocking)
|
84
|
-
|
85
|
-
# if non_blocking is true and an exception is raised, this won't get called
|
86
|
-
@pipe[:read].read(1) if clear_reads_on_pop?
|
87
|
-
|
88
|
-
rv
|
89
|
-
end
|
90
|
-
|
91
|
-
def close
|
92
|
-
@pipe.values.each { |io| io.close unless io.closed? }
|
93
|
-
end
|
94
|
-
|
95
|
-
def selectable_io
|
96
|
-
@pipe[:read]
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
def clear_reads_on_pop?
|
101
|
-
@clear_reads_on_pop
|
102
|
-
end
|
103
|
-
|
104
|
-
def logger
|
105
|
-
Zookeeper.logger
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
62
|
# used for internal dispatching
|
110
63
|
module JavaCB #:nodoc:
|
111
64
|
class Callback
|
@@ -216,43 +169,48 @@ class ZookeeperBase
|
|
216
169
|
end
|
217
170
|
end
|
218
171
|
|
172
|
+
attr_reader :event_queue
|
173
|
+
|
219
174
|
def reopen(timeout=10, watcher=nil)
|
220
|
-
|
175
|
+
# watcher ||= @default_watcher
|
221
176
|
|
222
|
-
@
|
177
|
+
@mutex.synchronize do
|
223
178
|
# flushes all outstanding watcher reqs.
|
224
|
-
@
|
225
|
-
set_default_global_watcher
|
179
|
+
@watcher_reqs.clear
|
180
|
+
set_default_global_watcher
|
181
|
+
|
182
|
+
replace_jzk!
|
183
|
+
wait_until_connected
|
226
184
|
end
|
227
185
|
|
228
|
-
|
229
|
-
|
186
|
+
state
|
187
|
+
end
|
188
|
+
|
189
|
+
def wait_until_connected(timeout=10)
|
190
|
+
time_to_stop = timeout ? (Time.now + timeout) : nil
|
230
191
|
|
231
|
-
|
232
|
-
|
233
|
-
until connected?
|
234
|
-
break if Time.now > time_to_stop
|
235
|
-
sleep 0.1
|
236
|
-
end
|
237
|
-
end
|
192
|
+
until connected? or (time_to_stop and Time.now > time_to_stop)
|
193
|
+
Thread.pass
|
238
194
|
end
|
239
195
|
|
240
|
-
|
196
|
+
connected?
|
241
197
|
end
|
242
198
|
|
243
199
|
def initialize(host, timeout=10, watcher=nil, options={})
|
244
200
|
@host = host
|
245
201
|
@event_queue = QueueWithPipe.new
|
246
202
|
@current_req_id = 0
|
247
|
-
|
203
|
+
|
204
|
+
@mutex = Monitor.new
|
205
|
+
@dispatch_shutdown_cond = @mutex.new_cond
|
206
|
+
|
248
207
|
@watcher_reqs = {}
|
249
208
|
@completion_reqs = {}
|
250
209
|
@_running = nil
|
251
210
|
@_closed = false
|
252
211
|
@options = {}
|
253
|
-
@start_stop_mutex = Mutex.new
|
254
212
|
|
255
|
-
watcher
|
213
|
+
@default_watcher = (watcher || get_default_global_watcher)
|
256
214
|
|
257
215
|
# allows connected-state handlers to be registered before
|
258
216
|
yield self if block_given?
|
@@ -263,8 +221,19 @@ class ZookeeperBase
|
|
263
221
|
setup_dispatch_thread!
|
264
222
|
end
|
265
223
|
|
224
|
+
def close
|
225
|
+
@mutex.synchronize do
|
226
|
+
return if @_closed
|
227
|
+
@_closed = true # these are probably unnecessary
|
228
|
+
@_running = false
|
229
|
+
|
230
|
+
stop_dispatch_thread!
|
231
|
+
@jzk.close if @jzk
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
266
235
|
def state
|
267
|
-
@jzk.state
|
236
|
+
@mutex.synchronize { @jzk.state }
|
268
237
|
end
|
269
238
|
|
270
239
|
def connected?
|
@@ -300,11 +269,11 @@ class ZookeeperBase
|
|
300
269
|
watch_cb = watcher ? create_watcher(req_id, path) : false
|
301
270
|
|
302
271
|
if callback
|
303
|
-
|
272
|
+
jzk.getData(path, watch_cb, JavaCB::DataCallback.new(req_id), event_queue)
|
304
273
|
[Code::Ok, nil, nil] # the 'nil, nil' isn't strictly necessary here
|
305
274
|
else # sync
|
306
275
|
stat = JZKD::Stat.new
|
307
|
-
data = String.from_java_bytes(
|
276
|
+
data = String.from_java_bytes(jzk.getData(path, watch_cb, stat))
|
308
277
|
|
309
278
|
[Code::Ok, data, stat.to_hash]
|
310
279
|
end
|
@@ -316,10 +285,10 @@ class ZookeeperBase
|
|
316
285
|
version ||= ANY_VERSION
|
317
286
|
|
318
287
|
if callback
|
319
|
-
|
288
|
+
jzk.setData(path, data.to_java_bytes, version, JavaCB::StatCallback.new(req_id), event_queue)
|
320
289
|
[Code::Ok, nil]
|
321
290
|
else
|
322
|
-
stat =
|
291
|
+
stat = jzk.setData(path, data.to_java_bytes, version).to_hash
|
323
292
|
[Code::Ok, stat]
|
324
293
|
end
|
325
294
|
end
|
@@ -330,11 +299,11 @@ class ZookeeperBase
|
|
330
299
|
watch_cb = watcher ? create_watcher(req_id, path) : false
|
331
300
|
|
332
301
|
if callback
|
333
|
-
|
302
|
+
jzk.getChildren(path, watch_cb, JavaCB::Children2Callback.new(req_id), event_queue)
|
334
303
|
[Code::Ok, nil, nil]
|
335
304
|
else
|
336
305
|
stat = JZKD::Stat.new
|
337
|
-
children =
|
306
|
+
children = jzk.getChildren(path, watch_cb, stat)
|
338
307
|
[Code::Ok, children.to_a, stat.to_hash]
|
339
308
|
end
|
340
309
|
end
|
@@ -348,21 +317,28 @@ class ZookeeperBase
|
|
348
317
|
data ||= ''
|
349
318
|
|
350
319
|
if callback
|
351
|
-
|
320
|
+
jzk.create(path, data.to_java_bytes, acl, mode, JavaCB::StringCallback.new(req_id), event_queue)
|
352
321
|
[Code::Ok, nil]
|
353
322
|
else
|
354
|
-
new_path =
|
323
|
+
new_path = jzk.create(path, data.to_java_bytes, acl, mode)
|
355
324
|
[Code::Ok, new_path]
|
356
325
|
end
|
357
326
|
end
|
358
327
|
end
|
359
328
|
|
329
|
+
def sync(req_id, path)
|
330
|
+
handle_keeper_exception do
|
331
|
+
jzk.sync(path, JavaCB::VoidCallback.new(req_id), event_queue)
|
332
|
+
Code::Ok
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
360
336
|
def delete(req_id, path, version, callback)
|
361
337
|
handle_keeper_exception do
|
362
338
|
if callback
|
363
|
-
|
339
|
+
jzk.delete(path, version, JavaCB::VoidCallback.new(req_id), event_queue)
|
364
340
|
else
|
365
|
-
|
341
|
+
jzk.delete(path, version)
|
366
342
|
end
|
367
343
|
|
368
344
|
Code::Ok
|
@@ -376,9 +352,9 @@ class ZookeeperBase
|
|
376
352
|
logger.debug { "set_acl: converted #{acl.inspect}" }
|
377
353
|
|
378
354
|
if callback
|
379
|
-
|
355
|
+
jzk.setACL(path, acl, version, JavaCB::ACLCallback.new(req_id), event_queue)
|
380
356
|
else
|
381
|
-
|
357
|
+
jzk.setACL(path, acl, version)
|
382
358
|
end
|
383
359
|
|
384
360
|
Code::Ok
|
@@ -390,10 +366,10 @@ class ZookeeperBase
|
|
390
366
|
watch_cb = watcher ? create_watcher(req_id, path) : false
|
391
367
|
|
392
368
|
if callback
|
393
|
-
|
369
|
+
jzk.exists(path, watch_cb, JavaCB::StatCallback.new(req_id), event_queue)
|
394
370
|
[Code::Ok, nil, nil]
|
395
371
|
else
|
396
|
-
stat =
|
372
|
+
stat = jzk.exists(path, watch_cb)
|
397
373
|
[Code::Ok, (stat and stat.to_hash)]
|
398
374
|
end
|
399
375
|
end
|
@@ -405,10 +381,10 @@ class ZookeeperBase
|
|
405
381
|
|
406
382
|
if callback
|
407
383
|
logger.debug { "calling getACL, path: #{path.inspect}, stat: #{stat.inspect}" }
|
408
|
-
|
384
|
+
jzk.getACL(path, stat, JavaCB::ACLCallback.new(req_id), event_queue)
|
409
385
|
[Code::Ok, nil, nil]
|
410
386
|
else
|
411
|
-
acls =
|
387
|
+
acls = jzk.getACL(path, stat).map { |a| a.to_hash }
|
412
388
|
|
413
389
|
[Code::Ok, Array(acls).map{|m| m.to_hash}, stat.to_hash]
|
414
390
|
end
|
@@ -420,80 +396,30 @@ class ZookeeperBase
|
|
420
396
|
raise ZookeeperException::NotConnected unless connected?
|
421
397
|
end
|
422
398
|
|
423
|
-
KILL_TOKEN = :__kill_token__
|
424
|
-
|
425
|
-
class DispatchShutdownException < StandardError; end
|
426
|
-
|
427
|
-
def wake_event_loop!
|
428
|
-
@event_queue.push(KILL_TOKEN) # ignored by dispatch_next_callback
|
429
|
-
end
|
430
|
-
|
431
|
-
def close
|
432
|
-
@req_mutex.synchronize do
|
433
|
-
@_running = false if @_running
|
434
|
-
end
|
435
|
-
|
436
|
-
# XXX: why is wake_event_loop! here?
|
437
|
-
if @dispatcher
|
438
|
-
wake_event_loop!
|
439
|
-
@dispatcher.join
|
440
|
-
end
|
441
|
-
|
442
|
-
unless @_closed
|
443
|
-
@start_stop_mutex.synchronize do
|
444
|
-
@_closed = true
|
445
|
-
close_handle
|
446
|
-
end
|
447
|
-
|
448
|
-
@event_queue.close
|
449
|
-
end
|
450
|
-
end
|
451
|
-
|
452
|
-
def close_handle
|
453
|
-
if @jzk
|
454
|
-
@jzk.close
|
455
|
-
wait_until { !connected? }
|
456
|
-
end
|
457
|
-
end
|
458
|
-
|
459
399
|
# set the watcher object/proc that will receive all global events (such as session/state events)
|
460
400
|
#---
|
461
401
|
# XXX: this code needs to be duplicated from ext/zookeeper_base.rb because
|
462
402
|
# it's called from the initializer, and because of the C impl. we can't have
|
463
403
|
# the two decend from a common base, and a module wouldn't work
|
464
|
-
def set_default_global_watcher
|
465
|
-
@
|
466
|
-
@default_watcher = block
|
404
|
+
def set_default_global_watcher
|
405
|
+
@mutex.synchronize do
|
467
406
|
@watcher_reqs[ZKRB_GLOBAL_CB_REQ] = { :watcher => @default_watcher, :watcher_context => nil }
|
468
407
|
end
|
469
408
|
end
|
470
409
|
|
471
|
-
# by accessing this selectable_io you indicate that you intend to clear it
|
472
|
-
# when you have delivered an event by reading one byte per event.
|
473
|
-
#
|
474
|
-
def selectable_io
|
475
|
-
@event_queue.clear_reads_on_pop = false
|
476
|
-
@event_queue.selectable_io
|
477
|
-
end
|
478
|
-
|
479
410
|
def session_id
|
480
|
-
|
411
|
+
jzk.session_id
|
481
412
|
end
|
482
413
|
|
483
414
|
def session_passwd
|
484
|
-
|
415
|
+
jzk.session_passwd.to_s
|
485
416
|
end
|
486
417
|
|
487
|
-
def get_next_event(blocking=true)
|
488
|
-
@event_queue.pop(!blocking).tap do |event|
|
489
|
-
logger.debug { "get_next_event delivering event: #{event.inspect}" }
|
490
|
-
raise DispatchShutdownException if event == KILL_TOKEN
|
491
|
-
end
|
492
|
-
rescue ThreadError
|
493
|
-
nil
|
494
|
-
end
|
495
|
-
|
496
418
|
protected
|
419
|
+
def jzk
|
420
|
+
@mutex.synchronize { @jzk }
|
421
|
+
end
|
422
|
+
|
497
423
|
def handle_keeper_exception
|
498
424
|
yield
|
499
425
|
rescue JZK::KeeperException => e
|
@@ -513,7 +439,7 @@ class ZookeeperBase
|
|
513
439
|
lambda do |event|
|
514
440
|
logger.debug { "watcher for req_id #{req_id}, path: #{path} called back" }
|
515
441
|
h = { :req_id => req_id, :type => event.type.int_value, :state => event.state.int_value, :path => path }
|
516
|
-
|
442
|
+
event_queue.push(h)
|
517
443
|
end
|
518
444
|
end
|
519
445
|
|
@@ -534,20 +460,12 @@ class ZookeeperBase
|
|
534
460
|
}
|
535
461
|
end
|
536
462
|
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
rescue DispatchShutdownException
|
544
|
-
logger.info { "dispatch thread exiting, got shutdown exception" }
|
545
|
-
break
|
546
|
-
rescue Exception => e
|
547
|
-
$stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
|
548
|
-
end
|
549
|
-
end
|
550
|
-
end
|
463
|
+
private
|
464
|
+
def replace_jzk!
|
465
|
+
orig_jzk = @jzk
|
466
|
+
@jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue))
|
467
|
+
ensure
|
468
|
+
orig_jzk.close if orig_jzk
|
551
469
|
end
|
552
470
|
end
|
553
471
|
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ZookeeperCommon
|
2
|
+
# Ceci n'est pas une pipe
|
3
|
+
class QueueWithPipe
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :@queue, :clear
|
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
|
+
# r, w = IO.pipe
|
17
|
+
# @pipe = { :read => r, :write => w }
|
18
|
+
@queue = Queue.new
|
19
|
+
|
20
|
+
# with the EventMachine client, we want to let EM handle clearing the
|
21
|
+
# event pipe, so we set this to false
|
22
|
+
# @clear_reads_on_pop = true
|
23
|
+
|
24
|
+
@mutex = Mutex.new
|
25
|
+
@closed = false
|
26
|
+
@graceful = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def push(obj)
|
30
|
+
logger.debug { "#{self.class}##{__method__} obj: #{obj.inspect}, kill_token? #{obj == KILL_TOKEN}" }
|
31
|
+
@queue.push(obj)
|
32
|
+
end
|
33
|
+
|
34
|
+
def pop(non_blocking=false)
|
35
|
+
raise ShutdownException if closed? # this may get us in trouble
|
36
|
+
|
37
|
+
rv = @queue.pop(non_blocking)
|
38
|
+
|
39
|
+
if rv == KILL_TOKEN
|
40
|
+
close
|
41
|
+
raise ShutdownException
|
42
|
+
end
|
43
|
+
|
44
|
+
rv
|
45
|
+
end
|
46
|
+
|
47
|
+
# close the queue and causes ShutdownException to be raised on waiting threads
|
48
|
+
def graceful_close!
|
49
|
+
@mutex.synchronize do
|
50
|
+
return if @graceful or @closed
|
51
|
+
logger.debug { "#{self.class}##{__method__} gracefully closing" }
|
52
|
+
@graceful = true
|
53
|
+
push(KILL_TOKEN)
|
54
|
+
end
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def close
|
59
|
+
@mutex.synchronize do
|
60
|
+
return if @closed
|
61
|
+
@closed = true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def closed?
|
66
|
+
@mutex.synchronize { !!@closed }
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def clear_reads_on_pop?
|
71
|
+
@clear_reads_on_pop
|
72
|
+
end
|
73
|
+
|
74
|
+
def logger
|
75
|
+
Zookeeper.logger
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/zookeeper/common.rb
CHANGED
@@ -4,15 +4,22 @@ module ZookeeperCommon
|
|
4
4
|
# sigh, i guess define this here?
|
5
5
|
ZKRB_GLOBAL_CB_REQ = -1
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
super(blocking)
|
7
|
+
def event_dispatch_thread?
|
8
|
+
@dispatcher && (@dispatcher == Thread.current)
|
10
9
|
end
|
11
10
|
|
12
11
|
protected
|
12
|
+
def get_next_event(blocking=true)
|
13
|
+
@event_queue.pop(!blocking).tap do |event|
|
14
|
+
logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
|
15
|
+
end
|
16
|
+
rescue ThreadError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
13
20
|
def setup_call(meth_name, opts)
|
14
21
|
req_id = nil
|
15
|
-
@
|
22
|
+
@mutex.synchronize {
|
16
23
|
req_id = @current_req_id
|
17
24
|
@current_req_id += 1
|
18
25
|
setup_completion(req_id, meth_name, opts) if opts[:callback]
|
@@ -38,20 +45,65 @@ protected
|
|
38
45
|
end
|
39
46
|
|
40
47
|
def get_watcher(req_id)
|
41
|
-
@
|
48
|
+
@mutex.synchronize {
|
42
49
|
(req_id == ZKRB_GLOBAL_CB_REQ) ? @watcher_reqs[req_id] : @watcher_reqs.delete(req_id)
|
43
50
|
}
|
44
51
|
end
|
45
52
|
|
46
53
|
def get_completion(req_id)
|
47
|
-
@
|
54
|
+
@mutex.synchronize { @completion_reqs.delete(req_id) }
|
48
55
|
end
|
49
56
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
57
|
+
def setup_dispatch_thread!
|
58
|
+
logger.debug { "starting dispatch thread" }
|
59
|
+
@dispatcher ||= Thread.new do
|
60
|
+
while true
|
61
|
+
begin
|
62
|
+
dispatch_next_callback(get_next_event(true))
|
63
|
+
rescue QueueWithPipe::ShutdownException
|
64
|
+
logger.info { "dispatch thread exiting, got shutdown exception" }
|
65
|
+
break
|
66
|
+
rescue Exception => e
|
67
|
+
$stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
signal_dispatch_thread_exit!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# this method is part of the reopen/close code, and is responsible for
|
75
|
+
# shutting down the dispatch thread.
|
76
|
+
#
|
77
|
+
# @dispatcher will be nil when this method exits
|
78
|
+
#
|
79
|
+
def stop_dispatch_thread!
|
80
|
+
logger.debug { "#{self.class}##{__method__}" }
|
81
|
+
|
82
|
+
if @dispatcher
|
83
|
+
@mutex.synchronize do
|
84
|
+
event_queue.graceful_close!
|
85
|
+
|
86
|
+
# we now release the mutex so that dispatch_next_callback can grab it
|
87
|
+
# to do what it needs to do while delivering events
|
88
|
+
@dispatch_shutdown_cond.wait
|
53
89
|
|
90
|
+
@dispatcher.join
|
91
|
+
@dispatcher = nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def signal_dispatch_thread_exit!
|
97
|
+
@mutex.synchronize do
|
98
|
+
logger.debug { "dispatch thread exiting!" }
|
99
|
+
@dispatch_shutdown_cond.broadcast
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def dispatch_next_callback(hash)
|
54
104
|
return nil unless hash
|
105
|
+
|
106
|
+
Zookeeper.logger.debug { "get_next_event returned: #{prettify_event(hash).inspect}" }
|
55
107
|
|
56
108
|
is_completion = hash.has_key?(:rc)
|
57
109
|
|
@@ -96,4 +148,16 @@ protected
|
|
96
148
|
"Required arguments are: #{required.inspect}, but only the arguments #{args.keys.inspect} were supplied."
|
97
149
|
end
|
98
150
|
end
|
151
|
+
|
152
|
+
private
|
153
|
+
def prettify_event(hash)
|
154
|
+
hash.dup.tap do |h|
|
155
|
+
# pretty up the event display
|
156
|
+
h[:type] = ZookeeperConstants::EVENT_TYPE_NAMES.fetch(h[:type]) if h[:type]
|
157
|
+
h[:state] = ZookeeperConstants::STATE_NAMES.fetch(h[:state]) if h[:state]
|
158
|
+
h[:req_id] = :global_session if h[:req_id] == -1
|
159
|
+
end
|
160
|
+
end
|
99
161
|
end
|
162
|
+
|
163
|
+
require 'zookeeper/common/queue_with_pipe'
|
data/lib/zookeeper/constants.rb
CHANGED
@@ -18,6 +18,34 @@ module ZookeeperConstants
|
|
18
18
|
ZOO_CHILD_EVENT = 4
|
19
19
|
ZOO_SESSION_EVENT = -1
|
20
20
|
ZOO_NOTWATCHING_EVENT = -2
|
21
|
+
|
22
|
+
# only used by the C extension
|
23
|
+
ZOO_LOG_LEVEL_ERROR = 1
|
24
|
+
ZOO_LOG_LEVEL_WARN = 2
|
25
|
+
ZOO_LOG_LEVEL_INFO = 3
|
26
|
+
ZOO_LOG_LEVEL_DEBUG = 4
|
27
|
+
|
28
|
+
# used to find the name for a numeric event
|
29
|
+
# @private
|
30
|
+
EVENT_TYPE_NAMES = {
|
31
|
+
1 => :created,
|
32
|
+
2 => :deleted,
|
33
|
+
3 => :changed,
|
34
|
+
4 => :child,
|
35
|
+
-1 => :session,
|
36
|
+
-2 => :notwatching,
|
37
|
+
}
|
38
|
+
|
39
|
+
# used to pretty print the state name
|
40
|
+
# @private
|
41
|
+
STATE_NAMES = {
|
42
|
+
-112 => :expired_session,
|
43
|
+
-113 => :auth_failed,
|
44
|
+
0 => :closed,
|
45
|
+
1 => :connecting,
|
46
|
+
2 => :associating,
|
47
|
+
3 => :connected,
|
48
|
+
}
|
21
49
|
|
22
50
|
def print_events
|
23
51
|
puts "ZK events:"
|