zookeeper 0.9.3-java

Sign up to get free protection for your applications and to get access to all the features.
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
+