zookeeper 0.9.3-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.
Files changed (53) hide show
  1. data/.gitignore +10 -0
  2. data/CHANGELOG +119 -0
  3. data/Gemfile +17 -0
  4. data/LICENSE +23 -0
  5. data/Manifest +29 -0
  6. data/README.markdown +59 -0
  7. data/Rakefile +139 -0
  8. data/examples/cloud_config.rb +125 -0
  9. data/ext/.gitignore +6 -0
  10. data/ext/Rakefile +51 -0
  11. data/ext/c_zookeeper.rb +212 -0
  12. data/ext/dbg.h +53 -0
  13. data/ext/depend +5 -0
  14. data/ext/extconf.rb +85 -0
  15. data/ext/generate_gvl_code.rb +316 -0
  16. data/ext/zkc-3.3.5.tar.gz +0 -0
  17. data/ext/zkrb_wrapper.c +731 -0
  18. data/ext/zkrb_wrapper.h +330 -0
  19. data/ext/zkrb_wrapper_compat.c +15 -0
  20. data/ext/zkrb_wrapper_compat.h +11 -0
  21. data/ext/zookeeper_base.rb +211 -0
  22. data/ext/zookeeper_c.c +725 -0
  23. data/ext/zookeeper_lib.c +677 -0
  24. data/ext/zookeeper_lib.h +172 -0
  25. data/java/zookeeper_base.rb +477 -0
  26. data/lib/zookeeper.rb +297 -0
  27. data/lib/zookeeper/acls.rb +40 -0
  28. data/lib/zookeeper/callbacks.rb +91 -0
  29. data/lib/zookeeper/common.rb +174 -0
  30. data/lib/zookeeper/common/queue_with_pipe.rb +78 -0
  31. data/lib/zookeeper/constants.rb +57 -0
  32. data/lib/zookeeper/em_client.rb +55 -0
  33. data/lib/zookeeper/exceptions.rb +100 -0
  34. data/lib/zookeeper/stat.rb +21 -0
  35. data/lib/zookeeper/version.rb +6 -0
  36. data/notes.txt +14 -0
  37. data/spec/c_zookeeper_spec.rb +50 -0
  38. data/spec/chrooted_connection_spec.rb +81 -0
  39. data/spec/default_watcher_spec.rb +41 -0
  40. data/spec/em_spec.rb +51 -0
  41. data/spec/log4j.properties +17 -0
  42. data/spec/shared/all_success_return_values.rb +10 -0
  43. data/spec/shared/connection_examples.rb +1018 -0
  44. data/spec/spec_helper.rb +119 -0
  45. data/spec/support/progress_formatter.rb +15 -0
  46. data/spec/zookeeper_spec.rb +24 -0
  47. data/test/test_basic.rb +37 -0
  48. data/test/test_callback1.rb +36 -0
  49. data/test/test_close.rb +16 -0
  50. data/test/test_esoteric.rb +7 -0
  51. data/test/test_watcher1.rb +56 -0
  52. data/test/test_watcher2.rb +52 -0
  53. metadata +181 -0
@@ -0,0 +1,172 @@
1
+ #ifndef ZOOKEEPER_LIB_H
2
+ #define ZOOKEEPER_LIB_H
3
+
4
+ #include "ruby.h"
5
+ #include "c-client-src/zookeeper.h"
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+
10
+ #define ZK_TRUE 1
11
+ #define ZK_FALSE 0
12
+ #define ZKRB_GLOBAL_REQ -1
13
+
14
+ // (slyphon): this RC value does not conflict with any of the ZOO_ERRORS
15
+ // but need to find a better way of formalizing and defining this stuff
16
+ #define ZKRB_ERR_REQ -2
17
+ #define ZKRB_ERR_RC -15
18
+
19
+ #ifndef RSTRING_LEN
20
+ # define RSTRING_LEN(x) RSTRING(x)->len
21
+ #endif
22
+ #ifndef RSTRING_PTR
23
+ # define RSTRING_PTR(x) RSTRING(x)->ptr
24
+ #endif
25
+ #ifndef RARRAY_LEN
26
+ # define RARRAY_LEN(x) RARRAY(x)->len
27
+ #endif
28
+
29
+ extern int ZKRBDebugging;
30
+ extern pthread_mutex_t zkrb_q_mutex;
31
+
32
+ struct zkrb_data_completion {
33
+ char *data;
34
+ int data_len;
35
+ struct Stat *stat;
36
+ };
37
+
38
+ struct zkrb_stat_completion {
39
+ struct Stat *stat;
40
+ };
41
+
42
+ struct zkrb_void_completion {
43
+ };
44
+
45
+ struct zkrb_string_completion {
46
+ char *value;
47
+ };
48
+
49
+ struct zkrb_strings_completion {
50
+ struct String_vector *values;
51
+ };
52
+
53
+ struct zkrb_strings_stat_completion {
54
+ struct String_vector *values;
55
+ struct Stat *stat;
56
+ };
57
+
58
+ struct zkrb_acl_completion {
59
+ struct ACL_vector *acl;
60
+ struct Stat *stat;
61
+ };
62
+
63
+ struct zkrb_watcher_completion {
64
+ int type;
65
+ int state;
66
+ char *path;
67
+ };
68
+
69
+ typedef struct {
70
+ int64_t req_id;
71
+ int rc;
72
+
73
+ enum {
74
+ ZKRB_DATA = 0,
75
+ ZKRB_STAT = 1,
76
+ ZKRB_VOID = 2,
77
+ ZKRB_STRING = 3,
78
+ ZKRB_STRINGS = 4,
79
+ ZKRB_STRINGS_STAT = 5,
80
+ ZKRB_ACL = 6,
81
+ ZKRB_WATCHER = 7
82
+ } type;
83
+
84
+ union {
85
+ struct zkrb_data_completion *data_completion;
86
+ struct zkrb_stat_completion *stat_completion;
87
+ struct zkrb_void_completion *void_completion;
88
+ struct zkrb_string_completion *string_completion;
89
+ struct zkrb_strings_completion *strings_completion;
90
+ struct zkrb_strings_stat_completion *strings_stat_completion;
91
+ struct zkrb_acl_completion *acl_completion;
92
+ struct zkrb_watcher_completion *watcher_completion;
93
+ } completion;
94
+ } zkrb_event_t;
95
+
96
+ struct zkrb_event_ll {
97
+ zkrb_event_t *event;
98
+ struct zkrb_event_ll *next;
99
+ };
100
+
101
+ typedef struct zkrb_event_ll zkrb_event_ll_t;
102
+
103
+ typedef struct {
104
+ zkrb_event_ll_t *head;
105
+ zkrb_event_ll_t *tail;
106
+ int pipe_read;
107
+ int pipe_write;
108
+ } zkrb_queue_t;
109
+
110
+ zkrb_queue_t * zkrb_queue_alloc(void);
111
+ void zkrb_queue_free(zkrb_queue_t *queue);
112
+ zkrb_event_t * zkrb_event_alloc(void);
113
+ void zkrb_event_free(zkrb_event_t *ptr);
114
+
115
+ void zkrb_enqueue(zkrb_queue_t *queue, zkrb_event_t *elt);
116
+ zkrb_event_t * zkrb_peek(zkrb_queue_t *queue);
117
+ zkrb_event_t * zkrb_dequeue(zkrb_queue_t *queue, int need_lock);
118
+ void zkrb_signal(zkrb_queue_t *queue);
119
+
120
+ void zkrb_print_stat(const struct Stat *s);
121
+
122
+ typedef struct {
123
+ int64_t req_id;
124
+ zkrb_queue_t *queue;
125
+ } zkrb_calling_context;
126
+
127
+ void zkrb_print_calling_context(zkrb_calling_context *ctx);
128
+ zkrb_calling_context *zkrb_calling_context_alloc(int64_t req_id, zkrb_queue_t *queue);
129
+
130
+ /*
131
+ default process completions that get queued into the ruby client event queue
132
+ */
133
+
134
+ void zkrb_state_callback(
135
+ zhandle_t *zh, int type, int state, const char *path, void *calling_ctx);
136
+
137
+ void zkrb_data_callback(
138
+ int rc, const char *value, int value_len, const struct Stat *stat, const void *calling_ctx);
139
+
140
+ void zkrb_stat_callback(
141
+ int rc, const struct Stat *stat, const void *calling_ctx);
142
+
143
+ void zkrb_string_callback(
144
+ int rc, const char *string, const void *calling_ctx);
145
+
146
+ void zkrb_strings_callback(
147
+ int rc, const struct String_vector *strings, const void *calling_ctx);
148
+
149
+ void zkrb_strings_stat_callback(
150
+ int rc, const struct String_vector *strings, const struct Stat* stat, const void *calling_ctx);
151
+
152
+ void zkrb_void_callback(
153
+ int rc, const void *calling_ctx);
154
+
155
+ void zkrb_acl_callback(
156
+ int rc, struct ACL_vector *acls, struct Stat *stat, const void *calling_ctx);
157
+
158
+ VALUE zkrb_event_to_ruby(zkrb_event_t *event);
159
+ VALUE zkrb_acl_to_ruby(struct ACL *acl);
160
+ VALUE zkrb_acl_vector_to_ruby(struct ACL_vector *acl_vector);
161
+ VALUE zkrb_id_to_ruby(struct Id *id);
162
+ VALUE zkrb_string_vector_to_ruby(struct String_vector *string_vector);
163
+ VALUE zkrb_stat_to_rarray(const struct Stat *stat);
164
+ VALUE zkrb_stat_to_rhash(const struct Stat* stat);
165
+
166
+ struct ACL_vector * zkrb_ruby_to_aclvector(VALUE acl_ary);
167
+ struct ACL_vector * zkrb_clone_acl_vector(struct ACL_vector * src);
168
+ struct String_vector * zkrb_clone_string_vector(const struct String_vector * src);
169
+ struct ACL zkrb_ruby_to_acl(VALUE rubyacl);
170
+ struct Id zkrb_ruby_to_id(VALUE rubyid);
171
+
172
+ #endif /* ZOOKEEPER_LIB_H */
@@ -0,0 +1,477 @@
1
+ require 'java'
2
+ require 'thread'
3
+ require 'rubygems'
4
+
5
+ gem 'slyphon-log4j', '= 1.2.15'
6
+ gem 'slyphon-zookeeper_jar', '= 3.3.5'
7
+
8
+ require 'log4j'
9
+ require 'zookeeper_jar'
10
+
11
+ # The low-level wrapper-specific methods for the Java lib,
12
+ # subclassed by the top-level Zookeeper class
13
+ class ZookeeperBase
14
+ include Java
15
+ include ZookeeperCommon
16
+ include ZookeeperConstants
17
+ include ZookeeperCallbacks
18
+ include ZookeeperExceptions
19
+ include ZookeeperACLs
20
+ include ZookeeperStat
21
+
22
+ JZK = org.apache.zookeeper
23
+ JZKD = org.apache.zookeeper.data
24
+ Code = JZK::KeeperException::Code
25
+
26
+ ANY_VERSION = -1
27
+ DEFAULT_SESSION_TIMEOUT = 10_000
28
+
29
+ ZKRB_GLOBAL_CB_REQ = -1 unless defined?(ZKRB_GLOBAL_CB_REQ)
30
+
31
+ JZKD::Stat.class_eval do
32
+ MEMBERS = [:version, :czxid, :mzxid, :ctime, :mtime, :cversion, :aversion, :ephemeralOwner, :dataLength, :numChildren, :pzxid]
33
+ def to_hash
34
+ MEMBERS.inject({}) { |h,k| h[k] = __send__(k); h }
35
+ end
36
+ end
37
+
38
+ JZKD::Id.class_eval do
39
+ def to_hash
40
+ { :scheme => getScheme, :id => getId }
41
+ end
42
+ end
43
+
44
+ JZKD::ACL.class_eval do
45
+ def self.from_ruby_acl(acl)
46
+ raise TypeError, "acl must be a ZookeeperACLs::ACL not #{acl.inspect}" unless acl.kind_of?(ZookeeperACLs::ACL)
47
+ id = org.apache.zookeeper.data.Id.new(acl.id.scheme.to_s, acl.id.id.to_s)
48
+ new(acl.perms.to_i, id)
49
+ end
50
+
51
+ def to_hash
52
+ { :perms => getPerms, :id => getId.to_hash }
53
+ end
54
+ end
55
+
56
+ JZK::WatchedEvent.class_eval do
57
+ def to_hash
58
+ { :type => getType.getIntValue, :state => getState.getIntValue, :path => getPath }
59
+ end
60
+ end
61
+
62
+ # used for internal dispatching
63
+ module JavaCB #:nodoc:
64
+ class Callback
65
+ attr_reader :req_id
66
+
67
+ def initialize(req_id)
68
+ @req_id = req_id
69
+ end
70
+
71
+ protected
72
+ def logger
73
+ Zookeeper.logger
74
+ end
75
+ end
76
+
77
+ class DataCallback < Callback
78
+ include JZK::AsyncCallback::DataCallback
79
+
80
+ def processResult(rc, path, queue, data, stat)
81
+ logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, path: #{path}, queue: #{queue.inspect}, data: #{data.inspect}, stat: #{stat.inspect}" }
82
+
83
+ hash = {
84
+ :rc => rc,
85
+ :req_id => req_id,
86
+ :path => path,
87
+ :data => (data && String.from_java_bytes(data)),
88
+ :stat => (stat && stat.to_hash),
89
+ }
90
+
91
+ # if rc == Zookeeper::ZOK
92
+ # hash.merge!({
93
+ # :data => String.from_java_bytes(data),
94
+ # :stat => stat.to_hash,
95
+ # })
96
+ # end
97
+
98
+ queue.push(hash)
99
+ end
100
+ end
101
+
102
+ class StringCallback < Callback
103
+ include JZK::AsyncCallback::StringCallback
104
+
105
+ def processResult(rc, path, queue, str)
106
+ logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, path: #{path}, queue: #{queue.inspect}, str: #{str.inspect}" }
107
+ queue.push(:rc => rc, :req_id => req_id, :path => path, :string => str)
108
+ end
109
+ end
110
+
111
+ class StatCallback < Callback
112
+ include JZK::AsyncCallback::StatCallback
113
+
114
+ def processResult(rc, path, queue, stat)
115
+ logger.debug { "#{self.class.name}#processResult rc: #{rc.inspect}, req_id: #{req_id}, path: #{path.inspect}, queue: #{queue.inspect}, stat: #{stat.inspect}" }
116
+ queue.push(:rc => rc, :req_id => req_id, :stat => (stat and stat.to_hash), :path => path)
117
+ end
118
+ end
119
+
120
+ class Children2Callback < Callback
121
+ include JZK::AsyncCallback::Children2Callback
122
+
123
+ def processResult(rc, path, queue, children, stat)
124
+ logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, path: #{path}, queue: #{queue.inspect}, children: #{children.inspect}, stat: #{stat.inspect}" }
125
+ hash = {
126
+ :rc => rc,
127
+ :req_id => req_id,
128
+ :path => path,
129
+ :strings => (children && children.to_a),
130
+ :stat => (stat and stat.to_hash),
131
+ }
132
+
133
+ queue.push(hash)
134
+ end
135
+ end
136
+
137
+ class ACLCallback < Callback
138
+ include JZK::AsyncCallback::ACLCallback
139
+
140
+ def processResult(rc, path, queue, acl, stat)
141
+ logger.debug { "ACLCallback#processResult rc: #{rc.inspect}, req_id: #{req_id}, path: #{path.inspect}, queue: #{queue.inspect}, acl: #{acl.inspect}, stat: #{stat.inspect}" }
142
+ a = Array(acl).map { |a| a.to_hash }
143
+ queue.push(:rc => rc, :req_id => req_id, :path => path, :acl => a, :stat => (stat && stat.to_hash))
144
+ end
145
+ end
146
+
147
+ class VoidCallback < Callback
148
+ include JZK::AsyncCallback::VoidCallback
149
+
150
+ def processResult(rc, path, queue)
151
+ logger.debug { "#{self.class.name}#processResult rc: #{rc}, req_id: #{req_id}, queue: #{queue.inspect}" }
152
+ queue.push(:rc => rc, :req_id => req_id, :path => path)
153
+ end
154
+ end
155
+
156
+ class WatcherCallback < Callback
157
+ include JZK::Watcher
158
+
159
+ def initialize(event_queue)
160
+ @event_queue = event_queue
161
+ super(ZookeeperBase::ZKRB_GLOBAL_CB_REQ)
162
+ end
163
+
164
+ def process(event)
165
+ logger.debug { "WatcherCallback got event: #{event.to_hash.inspect}" }
166
+ hash = event.to_hash.merge(:req_id => req_id)
167
+ @event_queue.push(hash)
168
+ end
169
+ end
170
+ end
171
+
172
+ attr_reader :event_queue
173
+
174
+ def reopen(timeout=10, watcher=nil)
175
+ # watcher ||= @default_watcher
176
+
177
+ @mutex.synchronize do
178
+ # flushes all outstanding watcher reqs.
179
+ @watcher_reqs.clear
180
+ set_default_global_watcher
181
+
182
+ replace_jzk!
183
+ wait_until_connected
184
+ end
185
+
186
+ state
187
+ end
188
+
189
+ def wait_until_connected(timeout=10)
190
+ time_to_stop = timeout ? (Time.now + timeout) : nil
191
+
192
+ until connected? or (time_to_stop and Time.now > time_to_stop)
193
+ Thread.pass
194
+ end
195
+
196
+ connected?
197
+ end
198
+
199
+ def initialize(host, timeout=10, watcher=nil, options={})
200
+ @host = host
201
+ @event_queue = QueueWithPipe.new
202
+ @current_req_id = 0
203
+
204
+ @mutex = Monitor.new
205
+ @dispatch_shutdown_cond = @mutex.new_cond
206
+
207
+ @watcher_reqs = {}
208
+ @completion_reqs = {}
209
+ @_running = nil
210
+ @_closed = false
211
+ @options = {}
212
+
213
+ @default_watcher = (watcher || get_default_global_watcher)
214
+
215
+ # allows connected-state handlers to be registered before
216
+ yield self if block_given?
217
+
218
+ reopen(timeout)
219
+ return nil unless connected?
220
+ @_running = true
221
+ setup_dispatch_thread!
222
+ end
223
+
224
+ def close
225
+ shutdown_thread = Thread.new do
226
+ @mutex.synchronize do
227
+ unless @_closed
228
+ @_closed = true # these are probably unnecessary
229
+ @_running = false
230
+
231
+ stop_dispatch_thread!
232
+ @jzk.close if @jzk
233
+ end
234
+ end
235
+ end
236
+
237
+ shutdown_thread.join unless event_dispatch_thread?
238
+ end
239
+
240
+ def state
241
+ @mutex.synchronize { @jzk.state }
242
+ end
243
+
244
+ def connected?
245
+ state == JZK::ZooKeeper::States::CONNECTED
246
+ end
247
+
248
+ def connecting?
249
+ state == JZK::ZooKeeper::States::CONNECTING
250
+ end
251
+
252
+ def associating?
253
+ state == JZK::ZooKeeper::States::ASSOCIATING
254
+ end
255
+
256
+ def running?
257
+ @_running
258
+ end
259
+
260
+ def closed?
261
+ @_closed
262
+ end
263
+
264
+ def self.set_debug_level(*a)
265
+ # IGNORED IN JRUBY
266
+ end
267
+
268
+ def set_debug_level(*a)
269
+ # IGNORED IN JRUBY
270
+ end
271
+
272
+ def get(req_id, path, callback, watcher)
273
+ handle_keeper_exception do
274
+ watch_cb = watcher ? create_watcher(req_id, path) : false
275
+
276
+ if callback
277
+ jzk.getData(path, watch_cb, JavaCB::DataCallback.new(req_id), event_queue)
278
+ [Code::Ok, nil, nil] # the 'nil, nil' isn't strictly necessary here
279
+ else # sync
280
+ stat = JZKD::Stat.new
281
+ data = String.from_java_bytes(jzk.getData(path, watch_cb, stat))
282
+
283
+ [Code::Ok, data, stat.to_hash]
284
+ end
285
+ end
286
+ end
287
+
288
+ def set(req_id, path, data, callback, version)
289
+ handle_keeper_exception do
290
+ version ||= ANY_VERSION
291
+
292
+ if callback
293
+ jzk.setData(path, data.to_java_bytes, version, JavaCB::StatCallback.new(req_id), event_queue)
294
+ [Code::Ok, nil]
295
+ else
296
+ stat = jzk.setData(path, data.to_java_bytes, version).to_hash
297
+ [Code::Ok, stat]
298
+ end
299
+ end
300
+ end
301
+
302
+ def get_children(req_id, path, callback, watcher)
303
+ handle_keeper_exception do
304
+ watch_cb = watcher ? create_watcher(req_id, path) : false
305
+
306
+ if callback
307
+ jzk.getChildren(path, watch_cb, JavaCB::Children2Callback.new(req_id), event_queue)
308
+ [Code::Ok, nil, nil]
309
+ else
310
+ stat = JZKD::Stat.new
311
+ children = jzk.getChildren(path, watch_cb, stat)
312
+ [Code::Ok, children.to_a, stat.to_hash]
313
+ end
314
+ end
315
+ end
316
+
317
+ def create(req_id, path, data, callback, acl, flags)
318
+ handle_keeper_exception do
319
+ acl = Array(acl).map{ |a| JZKD::ACL.from_ruby_acl(a) }
320
+ mode = JZK::CreateMode.fromFlag(flags)
321
+
322
+ data ||= ''
323
+
324
+ if callback
325
+ jzk.create(path, data.to_java_bytes, acl, mode, JavaCB::StringCallback.new(req_id), event_queue)
326
+ [Code::Ok, nil]
327
+ else
328
+ new_path = jzk.create(path, data.to_java_bytes, acl, mode)
329
+ [Code::Ok, new_path]
330
+ end
331
+ end
332
+ end
333
+
334
+ def sync(req_id, path)
335
+ handle_keeper_exception do
336
+ jzk.sync(path, JavaCB::VoidCallback.new(req_id), event_queue)
337
+ Code::Ok
338
+ end
339
+ end
340
+
341
+ def delete(req_id, path, version, callback)
342
+ handle_keeper_exception do
343
+ if callback
344
+ jzk.delete(path, version, JavaCB::VoidCallback.new(req_id), event_queue)
345
+ else
346
+ jzk.delete(path, version)
347
+ end
348
+
349
+ Code::Ok
350
+ end
351
+ end
352
+
353
+ def set_acl(req_id, path, acl, callback, version)
354
+ handle_keeper_exception do
355
+ logger.debug { "set_acl: acl #{acl.inspect}" }
356
+ acl = Array(acl).flatten.map { |a| JZKD::ACL.from_ruby_acl(a) }
357
+ logger.debug { "set_acl: converted #{acl.inspect}" }
358
+
359
+ if callback
360
+ jzk.setACL(path, acl, version, JavaCB::ACLCallback.new(req_id), event_queue)
361
+ else
362
+ jzk.setACL(path, acl, version)
363
+ end
364
+
365
+ Code::Ok
366
+ end
367
+ end
368
+
369
+ def exists(req_id, path, callback, watcher)
370
+ handle_keeper_exception do
371
+ watch_cb = watcher ? create_watcher(req_id, path) : false
372
+
373
+ if callback
374
+ jzk.exists(path, watch_cb, JavaCB::StatCallback.new(req_id), event_queue)
375
+ [Code::Ok, nil, nil]
376
+ else
377
+ stat = jzk.exists(path, watch_cb)
378
+ [Code::Ok, (stat and stat.to_hash)]
379
+ end
380
+ end
381
+ end
382
+
383
+ def get_acl(req_id, path, callback)
384
+ handle_keeper_exception do
385
+ stat = JZKD::Stat.new
386
+
387
+ if callback
388
+ logger.debug { "calling getACL, path: #{path.inspect}, stat: #{stat.inspect}" }
389
+ jzk.getACL(path, stat, JavaCB::ACLCallback.new(req_id), event_queue)
390
+ [Code::Ok, nil, nil]
391
+ else
392
+ acls = jzk.getACL(path, stat).map { |a| a.to_hash }
393
+
394
+ [Code::Ok, Array(acls).map{|m| m.to_hash}, stat.to_hash]
395
+ end
396
+ end
397
+ end
398
+
399
+ def assert_open
400
+ # XXX don't know how to check for valid session state!
401
+ raise ZookeeperException::NotConnected unless connected?
402
+ end
403
+
404
+ # set the watcher object/proc that will receive all global events (such as session/state events)
405
+ #---
406
+ # XXX: this code needs to be duplicated from ext/zookeeper_base.rb because
407
+ # it's called from the initializer, and because of the C impl. we can't have
408
+ # the two decend from a common base, and a module wouldn't work
409
+ def set_default_global_watcher
410
+ @mutex.synchronize do
411
+ @watcher_reqs[ZKRB_GLOBAL_CB_REQ] = { :watcher => @default_watcher, :watcher_context => nil }
412
+ end
413
+ end
414
+
415
+ def session_id
416
+ jzk.session_id
417
+ end
418
+
419
+ def session_passwd
420
+ jzk.session_passwd.to_s
421
+ end
422
+
423
+ protected
424
+ def jzk
425
+ @mutex.synchronize { @jzk }
426
+ end
427
+
428
+ def handle_keeper_exception
429
+ yield
430
+ rescue JZK::KeeperException => e
431
+ e.cause.code.intValue
432
+ end
433
+
434
+ def call_type(callback, watcher)
435
+ if callback
436
+ watcher ? :async_watch : :async
437
+ else
438
+ watcher ? :sync_watch : :sync
439
+ end
440
+ end
441
+
442
+ def create_watcher(req_id, path)
443
+ logger.debug { "creating watcher for req_id: #{req_id} path: #{path}" }
444
+ lambda do |event|
445
+ logger.debug { "watcher for req_id #{req_id}, path: #{path} called back" }
446
+ h = { :req_id => req_id, :type => event.type.int_value, :state => event.state.int_value, :path => path }
447
+ event_queue.push(h)
448
+ end
449
+ end
450
+
451
+ # method to wait until block passed returns true or timeout (default is 10 seconds) is reached
452
+ def wait_until(timeout=10, &block)
453
+ time_to_stop = Time.now + timeout
454
+ until yield do
455
+ break if Time.now > time_to_stop
456
+ sleep 0.1
457
+ end
458
+ end
459
+
460
+ # TODO: Make all global puts configurable
461
+ def get_default_global_watcher
462
+ Proc.new { |args|
463
+ logger.debug { "Ruby ZK Global CB called type=#{event_by_value(args[:type])} state=#{state_by_value(args[:state])}" }
464
+ true
465
+ }
466
+ end
467
+
468
+ private
469
+ def replace_jzk!
470
+ orig_jzk = @jzk
471
+ @jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue))
472
+ ensure
473
+ orig_jzk.close if orig_jzk
474
+ end
475
+ end
476
+
477
+