zookeeper 1.4.4 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -202,11 +202,9 @@ class GeneratedCode < Struct.new(:structs, :wrapper_fns, :calling_fns)
202
202
 
203
203
  typed_args = argstr.split(',').map(&:strip)
204
204
 
205
- # gah, fix up zoo_aset_acl which has a void_completion_t with no name assigned
206
- if zoo_fn_name == 'zoo_aset_acl'
207
- if idx = typed_args.index('void_completion_t')
208
- typed_args[idx] = 'void_completion_t completion'
209
- end
205
+ # gah, fix up functions which have a void_completion_t with no name assigned
206
+ if idx = typed_args.index('void_completion_t')
207
+ typed_args[idx] = 'void_completion_t completion'
210
208
  end
211
209
 
212
210
  struct = CallStruct.new(zoo_fn_name, typed_args)
@@ -233,7 +231,7 @@ def render_header_file(code)
233
231
  #endif
234
232
 
235
233
  #include "ruby.h"
236
- #include "c-client-src/zookeeper.h"
234
+ #include "zookeeper/zookeeper.h"
237
235
  #include "zkrb_wrapper_compat.h"
238
236
  #include "dbg.h"
239
237
 
@@ -0,0 +1,41 @@
1
+ diff -ur zkc-3.4.5-orig/c/src/zookeeper.c zkc-3.4.5/c/src/zookeeper.c
2
+ --- zkc-3.4.5-orig/c/src/zookeeper.c 2012-09-30 10:53:32.000000000 -0700
3
+ +++ zkc-3.4.5/c/src/zookeeper.c 2013-09-07 21:25:24.000000000 -0700
4
+ @@ -1650,14 +1650,16 @@
5
+ // a PING
6
+ if (zh->state==ZOO_CONNECTED_STATE) {
7
+ send_to = zh->recv_timeout/3 - idle_send;
8
+ - if (send_to <= 0 && zh->sent_requests.head==0) {
9
+ -// LOG_DEBUG(("Sending PING to %s (exceeded idle by %dms)",
10
+ -// format_current_endpoint_info(zh),-send_to));
11
+ - int rc=send_ping(zh);
12
+ - if (rc < 0){
13
+ - LOG_ERROR(("failed to send PING request (zk retcode=%d)",rc));
14
+ - return api_epilog(zh,rc);
15
+ - }
16
+ + if (send_to <= 0) {
17
+ + if (zh->sent_requests.head==0) {
18
+ + LOG_DEBUG(("Sending PING to %s (exceeded idle by %dms)",
19
+ + format_current_endpoint_info(zh),-send_to));
20
+ + int rc=send_ping(zh);
21
+ + if (rc < 0){
22
+ + LOG_ERROR(("failed to send PING request (zk retcode=%d)",rc));
23
+ + return api_epilog(zh,rc);
24
+ + }
25
+ + }
26
+ send_to = zh->recv_timeout/3;
27
+ }
28
+ }
29
+ @@ -1669,6 +1671,12 @@
30
+ zh->next_deadline.tv_sec += zh->next_deadline.tv_usec / 1000000;
31
+ zh->next_deadline.tv_usec = zh->next_deadline.tv_usec % 1000000;
32
+ }
33
+ +
34
+ + if (tv->tv_sec == 0 && tv->tv_usec == 0) {
35
+ + LOG_DEBUG(("Returning a 0.0 timeval: state=%d idle_recv=%d idle_send=%d recv_to=%d send_to=%d send_requests=%s",
36
+ + zh->state, idle_recv, idle_send, recv_to, send_to, zh->sent_requests.head==0 ? "false" : "true"));
37
+ + }
38
+ +
39
+ *interest = ZOOKEEPER_READ;
40
+ /* we are interested in a write if we are connected and have something
41
+ * to send, or we are waiting for a connect to finish. */
Binary file
data/ext/zkrb.c CHANGED
@@ -73,7 +73,7 @@
73
73
  #include "ruby/io.h"
74
74
  #endif
75
75
 
76
- #include "c-client-src/zookeeper.h"
76
+ #include "zookeeper/zookeeper.h"
77
77
  #include <errno.h>
78
78
  #include <stdio.h>
79
79
  #include <stdlib.h>
@@ -82,6 +82,7 @@
82
82
  #include <pthread.h>
83
83
  #include <inttypes.h>
84
84
  #include <time.h>
85
+ #include <arpa/inet.h>
85
86
 
86
87
  #include "common.h"
87
88
  #include "event_lib.h"
@@ -242,7 +243,7 @@ static void print_zkrb_instance_data(zkrb_instance_data_t* ptr) {
242
243
  fprintf(stderr, "}\n");
243
244
  }
244
245
 
245
- #define session_timeout_msec(self) rb_iv_get(self, "@_session_timeout_msec")
246
+ #define receive_timeout_msec(self) rb_iv_get(self, "@_receive_timeout_msec")
246
247
 
247
248
  inline static void zkrb_debug_clientid_t(const clientid_t *cid) {
248
249
  int pass_len = sizeof(cid->passwd);
@@ -268,18 +269,28 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
268
269
  Check_Type(hostPort, T_STRING);
269
270
 
270
271
  // Look up :zkc_log_level
271
- VALUE log_level = rb_hash_aref(options, ID2SYM(rb_intern("zkc_log_level")));
272
- if (NIL_P(log_level)) {
273
- zoo_set_debug_level(0); // no log messages
274
- } else {
275
- Check_Type(log_level, T_FIXNUM);
276
- zoo_set_debug_level(FIX2INT(log_level));
277
- }
272
+ // VALUE log_level = rb_hash_aref(options, ID2SYM(rb_intern("zkc_log_level")));
273
+ // if (NIL_P(log_level)) {
274
+ // zoo_set_debug_level(0); // no log messages
275
+ // } else {
276
+ // Check_Type(log_level, T_FIXNUM);
277
+ // zoo_set_debug_level(FIX2INT(log_level));
278
+ // }
278
279
 
279
280
  volatile VALUE data;
280
281
  zkrb_instance_data_t *zk_local_ctx;
281
282
  data = Data_Make_Struct(CZookeeper, zkrb_instance_data_t, 0, free_zkrb_instance_data, zk_local_ctx);
282
283
 
284
+ // Look up :session_id and :session_passwd
285
+ VALUE session_id = rb_hash_aref(options, ID2SYM(rb_intern("session_id")));
286
+ VALUE password = rb_hash_aref(options, ID2SYM(rb_intern("session_passwd")));
287
+ if (!NIL_P(session_id) && !NIL_P(password)) {
288
+ Check_Type(password, T_STRING);
289
+
290
+ zk_local_ctx->myid.client_id = NUM2LL(session_id);
291
+ strncpy(zk_local_ctx->myid.passwd, RSTRING_PTR(password), 16);
292
+ }
293
+
283
294
  zk_local_ctx->queue = zkrb_queue_alloc();
284
295
 
285
296
  if (zk_local_ctx->queue == NULL)
@@ -296,7 +307,7 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
296
307
  zookeeper_init(
297
308
  RSTRING_PTR(hostPort), // const char *host
298
309
  zkrb_state_callback, // watcher_fn
299
- session_timeout_msec(self), // recv_timeout
310
+ receive_timeout_msec(self), // recv_timeout
300
311
  &zk_local_ctx->myid, // cilentid_t
301
312
  ctx, // void *context
302
313
  0); // flags
@@ -323,7 +334,7 @@ static VALUE method_get_children(VALUE self, VALUE reqid, VALUE path, VALUE asyn
323
334
  struct String_vector strings;
324
335
  struct Stat stat;
325
336
 
326
- int rc;
337
+ int rc = 0;
327
338
  switch (call_type) {
328
339
 
329
340
  #ifdef THREADED
@@ -368,7 +379,7 @@ static VALUE method_exists(VALUE self, VALUE reqid, VALUE path, VALUE async, VAL
368
379
  VALUE output = Qnil;
369
380
  struct Stat stat;
370
381
 
371
- int rc;
382
+ int rc = 0;
372
383
  switch (call_type) {
373
384
 
374
385
  #ifdef THREADED
@@ -444,7 +455,7 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
444
455
 
445
456
  int invalid_call_type=0;
446
457
 
447
- int rc;
458
+ int rc = 0;
448
459
  switch (call_type) {
449
460
 
450
461
  #ifdef THREADED
@@ -516,7 +527,7 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
516
527
  char * data = NULL;
517
528
  if (IS_SYNC(call_type)) {
518
529
  data = malloc(MAX_ZNODE_SIZE); /* ugh */
519
- memset(data, 0, sizeof(data));
530
+ memset(data, 0, MAX_ZNODE_SIZE);
520
531
  }
521
532
 
522
533
  int rc, invalid_call_type=0;
@@ -778,10 +789,10 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
778
789
  fd_set rfds, wfds, efds;
779
790
  FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
780
791
 
781
- int fd=0, interest=0, events=0, rc=0, maxfd=0;
792
+ int fd = 0, interest = 0, events = 0, rc = 0, maxfd = 0, irc = 0, prc = 0;
782
793
  struct timeval tv;
783
794
 
784
- zookeeper_interest(zk->zh, &fd, &interest, &tv);
795
+ irc = zookeeper_interest(zk->zh, &fd, &interest, &tv);
785
796
 
786
797
  if (fd != -1) {
787
798
  if (interest & ZOOKEEPER_READ) {
@@ -824,17 +835,24 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
824
835
  rb_raise(rb_eRuntimeError, "read from pipe failed: %s", clean_errno());
825
836
  }
826
837
  }
827
-
828
- rc = zookeeper_process(zk->zh, events);
829
838
  }
830
839
  else if (rc == 0) {
831
- zkrb_debug("timed out waiting for descriptor to be ready");
840
+ // zkrb_debug("timed out waiting for descriptor to be ready. interest=%d fd=%d pipe_r_fd=%d maxfd=%d irc=%d timeout=%f",
841
+ // interest, fd, pipe_r_fd, maxfd, irc, tv.tv_sec + (tv.tv_usec/ 1000.0 / 1000.0));
832
842
  }
833
843
  else {
834
- log_err("select returned: %d", rc);
844
+ log_err("select returned an error: rc=%d interest=%d fd=%d pipe_r_fd=%d maxfd=%d irc=%d timeout=%f",
845
+ rc, interest, fd, pipe_r_fd, maxfd, irc, tv.tv_sec + (tv.tv_usec/ 1000.0 / 1000.0));
835
846
  }
836
847
 
837
- return INT2FIX(rc);
848
+ prc = zookeeper_process(zk->zh, events);
849
+
850
+ if (rc == 0) {
851
+ zkrb_debug("timed out waiting for descriptor to be ready. prc=%d interest=%d fd=%d pipe_r_fd=%d maxfd=%d irc=%d timeout=%f",
852
+ prc, interest, fd, pipe_r_fd, maxfd, irc, tv.tv_sec + (tv.tv_usec/ 1000.0 / 1000.0));
853
+ }
854
+
855
+ return INT2FIX(prc);
838
856
  }
839
857
 
840
858
  static VALUE method_has_events(VALUE self) {
@@ -918,6 +936,38 @@ static VALUE method_zerror(VALUE self, VALUE errc) {
918
936
  return rb_str_new2(zerror(FIX2INT(errc)));
919
937
  }
920
938
 
939
+ static VALUE method_connected_host(VALUE self) {
940
+ FETCH_DATA_PTR(self, zk);
941
+
942
+ struct sockaddr addr;
943
+ socklen_t addr_len = sizeof(addr);
944
+
945
+ if (zookeeper_get_connected_host(zk->zh, &addr, &addr_len) != NULL) {
946
+ char buf[255];
947
+ char addrstr[128];
948
+ void *inaddr;
949
+ int port;
950
+
951
+ #if defined(AF_INET6)
952
+ if(addr.sa_family==AF_INET6){
953
+ inaddr = &((struct sockaddr_in6 *) &addr)->sin6_addr;
954
+ port = ((struct sockaddr_in6 *) &addr)->sin6_port;
955
+ } else {
956
+ #endif
957
+ inaddr = &((struct sockaddr_in *) &addr)->sin_addr;
958
+ port = ((struct sockaddr_in *) &addr)->sin_port;
959
+ #if defined(AF_INET6)
960
+ }
961
+ #endif
962
+
963
+ inet_ntop(addr.sa_family, inaddr, addrstr, sizeof(addrstr)-1);
964
+ snprintf(buf, sizeof(buf), "%s:%d", addrstr, ntohs(port));
965
+ return rb_str_new2(buf);
966
+ }
967
+
968
+ return Qnil;
969
+ }
970
+
921
971
  static void zkrb_define_methods(void) {
922
972
  #define DEFINE_METHOD(M, ARGS) { \
923
973
  rb_define_method(CZookeeper, #M, method_ ## M, ARGS); }
@@ -953,6 +1003,7 @@ static void zkrb_define_methods(void) {
953
1003
  DEFINE_METHOD(sync, 2);
954
1004
  DEFINE_METHOD(zkrb_iterate_event_loop, 0);
955
1005
  DEFINE_METHOD(zkrb_get_next_event_st, 0);
1006
+ DEFINE_METHOD(connected_host, 0);
956
1007
 
957
1008
  // methods for the ruby-side event manager
958
1009
  DEFINE_METHOD(zkrb_get_next_event, 1);
@@ -985,7 +1036,9 @@ static VALUE zkrb_client_id_method_initialize(VALUE self) {
985
1036
 
986
1037
 
987
1038
  void Init_zookeeper_c() {
1039
+ // Don't debug by default
988
1040
  ZKRBDebugging = 0;
1041
+ zoo_set_debug_level(0);
989
1042
 
990
1043
  mZookeeper = rb_define_module("Zookeeper");
991
1044
  mZookeeperExceptions = rb_define_module_under(mZookeeper, "Exceptions");
data/ext/zkrb_wrapper.c CHANGED
@@ -381,6 +381,30 @@ int zkrb_call_zoo_aset_acl(zhandle_t *zh, const char *path, int version, struct
381
381
  }
382
382
 
383
383
 
384
+ static VALUE zkrb_gvl_zoo_amulti(void *data) {
385
+ zkrb_zoo_amulti_args_t *a = (zkrb_zoo_amulti_args_t *)data;
386
+ a->rc = zoo_amulti(a->zh, a->count, a->ops, a->results, a->completion, a->data);
387
+ return Qnil;
388
+ }
389
+
390
+ // wrapper that calls zoo_amulti via zkrb_gvl_zoo_amulti inside rb_thread_blocking_region
391
+ int zkrb_call_zoo_amulti(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results, void_completion_t completion, const void *data) {
392
+ zkrb_zoo_amulti_args_t args = {
393
+ .rc = ZKRB_FAIL,
394
+ .zh = zh,
395
+ .count = count,
396
+ .ops = ops,
397
+ .results = results,
398
+ .completion = completion,
399
+ .data = data
400
+ };
401
+
402
+ zkrb_thread_blocking_region(zkrb_gvl_zoo_amulti, (void *)&args);
403
+
404
+ return args.rc;
405
+ }
406
+
407
+
384
408
  static VALUE zkrb_gvl_zoo_add_auth(void *data) {
385
409
  zkrb_zoo_add_auth_args_t *a = (zkrb_zoo_add_auth_args_t *)data;
386
410
  a->rc = zoo_add_auth(a->zh, a->scheme, a->cert, a->certLen, a->completion, a->data);
@@ -729,3 +753,23 @@ int zkrb_call_zoo_set_acl(zhandle_t *zh, const char *path, int version, const st
729
753
  }
730
754
 
731
755
 
756
+ static VALUE zkrb_gvl_zoo_multi(void *data) {
757
+ zkrb_zoo_multi_args_t *a = (zkrb_zoo_multi_args_t *)data;
758
+ a->rc = zoo_multi(a->zh, a->count, a->ops, a->results);
759
+ return Qnil;
760
+ }
761
+
762
+ // wrapper that calls zoo_multi via zkrb_gvl_zoo_multi inside rb_thread_blocking_region
763
+ int zkrb_call_zoo_multi(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results) {
764
+ zkrb_zoo_multi_args_t args = {
765
+ .rc = ZKRB_FAIL,
766
+ .zh = zh,
767
+ .count = count,
768
+ .ops = ops,
769
+ .results = results
770
+ };
771
+
772
+ zkrb_thread_blocking_region(zkrb_gvl_zoo_multi, (void *)&args);
773
+
774
+ return args.rc;
775
+ }
data/ext/zkrb_wrapper.h CHANGED
@@ -7,7 +7,7 @@
7
7
  #endif
8
8
 
9
9
  #include "ruby.h"
10
- #include "c-client-src/zookeeper.h"
10
+ #include "zookeeper/zookeeper.h"
11
11
  #include "zkrb_wrapper_compat.h"
12
12
  #include "dbg.h"
13
13
 
@@ -157,6 +157,16 @@ typedef struct {
157
157
  int rc;
158
158
  } zkrb_zoo_aset_acl_args_t;
159
159
 
160
+ typedef struct {
161
+ zhandle_t *zh;
162
+ int count;
163
+ const zoo_op_t *ops;
164
+ zoo_op_result_t *results;
165
+ void_completion_t completion;
166
+ const void *data;
167
+ int rc;
168
+ } zkrb_zoo_amulti_args_t;
169
+
160
170
  typedef struct {
161
171
  zhandle_t *zh;
162
172
  const char* scheme;
@@ -295,6 +305,14 @@ typedef struct {
295
305
  int rc;
296
306
  } zkrb_zoo_set_acl_args_t;
297
307
 
308
+ typedef struct {
309
+ zhandle_t *zh;
310
+ int count;
311
+ const zoo_op_t *ops;
312
+ zoo_op_result_t *results;
313
+ int rc;
314
+ } zkrb_zoo_multi_args_t;
315
+
298
316
  int zkrb_call_zoo_recv_timeout(zhandle_t *zh);
299
317
  int zkrb_call_zoo_state(zhandle_t *zh);
300
318
  int zkrb_call_zoo_acreate(zhandle_t *zh, const char *path, const char *value, int valuelen, const struct ACL_vector *acl, int flags, string_completion_t completion, const void *data);
@@ -311,6 +329,7 @@ int zkrb_call_zoo_awget_children2(zhandle_t *zh, const char *path, watcher_fn wa
311
329
  int zkrb_call_zoo_async(zhandle_t *zh, const char *path, string_completion_t completion, const void *data);
312
330
  int zkrb_call_zoo_aget_acl(zhandle_t *zh, const char *path, acl_completion_t completion, const void *data);
313
331
  int zkrb_call_zoo_aset_acl(zhandle_t *zh, const char *path, int version, struct ACL_vector *acl, void_completion_t completion, const void *data);
332
+ int zkrb_call_zoo_amulti(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results, void_completion_t completion, const void *data);
314
333
  int zkrb_call_zoo_add_auth(zhandle_t *zh, const char* scheme, const char* cert, int certLen, void_completion_t completion, const void *data);
315
334
  int zkrb_call_zoo_create(zhandle_t *zh, const char *path, const char *value, int valuelen, const struct ACL_vector *acl, int flags, char *path_buffer, int path_buffer_len);
316
335
  int zkrb_call_zoo_delete(zhandle_t *zh, const char *path, int version);
@@ -326,5 +345,6 @@ int zkrb_call_zoo_get_children2(zhandle_t *zh, const char *path, int watch, stru
326
345
  int zkrb_call_zoo_wget_children2(zhandle_t *zh, const char *path, watcher_fn watcher, void* watcherCtx, struct String_vector *strings, struct Stat *stat);
327
346
  int zkrb_call_zoo_get_acl(zhandle_t *zh, const char *path, struct ACL_vector *acl, struct Stat *stat);
328
347
  int zkrb_call_zoo_set_acl(zhandle_t *zh, const char *path, int version, const struct ACL_vector *acl);
348
+ int zkrb_call_zoo_multi(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results);
329
349
 
330
350
  #endif /* ZKRB_WRAPPER_H */
@@ -27,7 +27,8 @@ class ZookeeperBase
27
27
  ZOO_LOG_LEVEL_DEBUG = 4
28
28
 
29
29
  def_delegators :czk, :get_children, :exists, :delete, :get, :set,
30
- :set_acl, :get_acl, :client_id, :sync, :add_auth, :wait_until_connected
30
+ :set_acl, :get_acl, :client_id, :sync, :add_auth, :wait_until_connected,
31
+ :connected_host
31
32
 
32
33
  def self.threadsafe_inquisitor(*syms)
33
34
  syms.each do |sym|
@@ -40,7 +41,8 @@ class ZookeeperBase
40
41
  end
41
42
  end
42
43
 
43
- threadsafe_inquisitor :connected?, :connecting?, :associating?, :running?
44
+ threadsafe_inquisitor :connected?, :connecting?, :associating?, :running?,
45
+ :shutting_down?
44
46
 
45
47
  attr_reader :event_queue
46
48
 
@@ -60,14 +62,14 @@ class ZookeeperBase
60
62
  end
61
63
  private :reopen_after_fork!
62
64
 
63
- def reopen(timeout = 10, watcher=nil)
65
+ def reopen(timeout = 10, watcher=nil, opts = {})
64
66
  raise "You cannot set the watcher to a different value this way anymore!" if watcher
65
67
 
66
68
  reopen_after_fork! if forked?
67
69
 
68
70
  @mutex.synchronize do
69
71
  @czk.close if @czk
70
- @czk = CZookeeper.new(@host, @event_queue)
72
+ @czk = CZookeeper.new(@host, @event_queue, opts)
71
73
 
72
74
  # flushes all outstanding watcher reqs.
73
75
  @req_registry.clear_watchers!
@@ -79,7 +81,7 @@ class ZookeeperBase
79
81
  state
80
82
  end
81
83
 
82
- def initialize(host, timeout = 10, watcher=nil)
84
+ def initialize(host, timeout = 10, watcher=nil, opts = {})
83
85
  # approximate the java behavior of raising java.lang.IllegalArgumentException if the host
84
86
  # argument ends with '/'
85
87
  raise ArgumentError, "Host argument #{host.inspect} may not end with /" if host.end_with?('/')
@@ -97,7 +99,7 @@ class ZookeeperBase
97
99
 
98
100
  yield self if block_given?
99
101
 
100
- reopen(timeout)
102
+ reopen(timeout, nil, opts)
101
103
  end
102
104
 
103
105
  # if either of these happen, the user will need to renegotiate a connection via reopen
data/java/java_base.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'java'
2
2
  require 'thread'
3
- require 'rubygems'
4
3
 
5
- gem 'slyphon-log4j', '= 1.2.15'
6
- gem 'slyphon-zookeeper_jar', '= 3.3.5'
4
+ # require 'rubygems'
5
+ # gem 'slyphon-log4j', '= 1.2.15'
6
+ # gem 'zk-ruby-zookeeper_jar', "= #{Zookeeper::DRIVER_VERSION}"
7
7
 
8
8
  require 'log4j'
9
9
  require 'zookeeper_jar'
@@ -182,13 +182,13 @@ class JavaBase
182
182
 
183
183
  attr_reader :event_queue
184
184
 
185
- def reopen(timeout=10, watcher=nil)
185
+ def reopen(timeout=10, watcher=nil, opts = {})
186
186
  # watcher ||= @default_watcher
187
187
 
188
188
  @mutex.synchronize do
189
189
  @req_registry.clear_watchers!
190
190
 
191
- replace_jzk!
191
+ replace_jzk!(opts)
192
192
  wait_until_connected
193
193
  end
194
194
 
@@ -220,7 +220,7 @@ class JavaBase
220
220
  # allows connected-state handlers to be registered before
221
221
  yield self if block_given?
222
222
 
223
- reopen(timeout)
223
+ reopen(timeout, nil, options)
224
224
  return nil unless connected?
225
225
  @_running = true
226
226
  setup_dispatch_thread!
@@ -283,8 +283,9 @@ class JavaBase
283
283
  [Code::Ok, nil, nil] # the 'nil, nil' isn't strictly necessary here
284
284
  else # sync
285
285
  stat = JZKD::Stat.new
286
- data = String.from_java_bytes(jzk.getData(path, watch_cb, stat))
287
286
 
287
+ value = jzk.getData(path, watch_cb, stat)
288
+ data = String.from_java_bytes(value) unless value.nil?
288
289
  [Code::Ok, data, stat.to_hash]
289
290
  end
290
291
  end
@@ -487,9 +488,13 @@ class JavaBase
487
488
  }
488
489
  end
489
490
 
490
- def replace_jzk!
491
+ def replace_jzk!(opts = {})
491
492
  orig_jzk = @jzk
492
- @jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self))
493
+ if opts.has_key?(:session_id) && opts.has_key(:session_passwd)
494
+ @jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self), opts.fetch(:session_id), opts.fetch(:session_passwd).to_java_bytes)
495
+ else
496
+ @jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self))
497
+ end
493
498
  ensure
494
499
  orig_jzk.close if orig_jzk
495
500
  end