zookeeper 1.1.0-java → 1.1.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.
data/CHANGELOG CHANGED
@@ -1,3 +1,17 @@
1
+ v1.1.1 Cleanup after code review (h/t @eric)
2
+
3
+ * While hunting down this bug: https://bugs.ruby-lang.org/issues/6438
4
+ Eric Lindvall made a number of helpful catches.
5
+
6
+ * Reduce syscall overhead by not using an unnecessary pipe in the event_lib.c
7
+ implementation
8
+
9
+ * More careful use of rb_raise, don't longjmp past necessary free() calls.
10
+
11
+ * More careful malloc in the get() implementation (we need to allocate 1MB
12
+ to hold the data in a znode, but only in the SYNC cases).
13
+
14
+
1
15
  v1.1.0 Rewrite C backend to use zookeeper_st, the async library
2
16
 
3
17
  * In order to ensure fork safety, a rewrite of the backend was necessary.
data/ext/event_lib.c CHANGED
@@ -21,7 +21,6 @@ slyphon@gmail.com
21
21
  */
22
22
 
23
23
  #include "ruby.h"
24
- #include "event_lib.h"
25
24
  #include "c-client-src/zookeeper.h"
26
25
  #include <errno.h>
27
26
  #include <stdio.h>
@@ -30,82 +29,59 @@ slyphon@gmail.com
30
29
  #include <unistd.h>
31
30
  #include <inttypes.h>
32
31
  #include "common.h"
32
+ #include "event_lib.h"
33
33
  #include "dbg.h"
34
34
 
35
+ #ifndef THREADED
36
+ #define USE_XMALLOC
37
+ #endif
38
+
35
39
  #define GET_SYM(str) ID2SYM(rb_intern(str))
36
40
 
37
41
  int ZKRBDebugging;
38
42
 
39
- #ifdef THREADED
40
-
43
+ #if THREADED
41
44
  pthread_mutex_t zkrb_q_mutex = PTHREAD_MUTEX_INITIALIZER;
45
+ #endif
42
46
 
43
47
  inline static int global_mutex_lock() {
44
- int rv = pthread_mutex_lock(&zkrb_q_mutex);
48
+ int rv=0;
49
+ #if THREADED
50
+ rv = pthread_mutex_lock(&zkrb_q_mutex);
45
51
  if (rv != 0) log_err("global_mutex_lock error");
52
+ #endif
46
53
  return rv;
47
54
  }
48
55
 
49
56
  inline static int global_mutex_unlock() {
50
- int rv = pthread_mutex_unlock(&zkrb_q_mutex);
57
+ int rv=0;
58
+ #if THREADED
59
+ rv = pthread_mutex_unlock(&zkrb_q_mutex);
51
60
  if (rv != 0) log_err("global_mutex_unlock error");
61
+ #endif
52
62
  return rv;
53
63
  }
54
64
 
55
- void atfork_prepare() {
56
- global_mutex_lock();
57
- }
58
-
59
- void atfork_parent() {
60
- global_mutex_unlock();
61
- }
62
-
63
- void atfork_child() {
64
- global_mutex_unlock();
65
- }
66
-
67
- // set up handlers to make sure the thread being forked holds the lock at the
68
- // time the process is copied, then immediately unlock the mutex in both parent
69
- // and children
70
- /*pthread_atfork(atfork_prepare, atfork_parent, atfork_child);*/
71
-
72
- // delegates to the system malloc (we can't use xmalloc in the threaded case,
73
- // as we can't touch the interpreter)
74
-
75
- inline static void* zk_malloc(size_t size) {
76
- return malloc(size);
77
- }
78
-
79
- inline static void zk_free(void *ptr) {
80
- free(ptr);
81
- }
82
-
83
- #else
84
-
85
- inline static int global_mutex_lock() {
86
- return 0;
87
- }
88
-
89
- inline static int global_mutex_unlock() {
90
- return 0;
91
- }
92
-
93
65
  // we can use the ruby xmalloc/xfree that will raise errors
94
66
  // in the case of a failure to allocate memory, and can cycle
95
67
  // the garbage collector in some cases.
96
68
 
97
69
  inline static void* zk_malloc(size_t size) {
70
+ #ifdef USE_XMALLOC
98
71
  return xmalloc(size);
72
+ #else
73
+ return malloc(size);
74
+ #endif
99
75
  }
100
76
 
101
77
  inline static void zk_free(void *ptr) {
78
+ #ifdef USE_XMALLOC
102
79
  xfree(ptr);
80
+ #else
81
+ free(ptr);
82
+ #endif
103
83
  }
104
84
 
105
-
106
- #endif /* THREADED */
107
-
108
-
109
85
  void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
110
86
  if (q == NULL) {
111
87
  zkrb_debug("zkrb_enqueue, queue ptr was NULL");
@@ -125,13 +101,15 @@ void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
125
101
  q->tail->event = NULL;
126
102
  q->tail->next = NULL;
127
103
 
128
- ssize_t ret = write(q->pipe_write, "0", 1); /* Wake up Ruby listener */
129
-
130
104
  global_mutex_unlock();
131
105
 
132
- if (ret < 0) {
106
+ #if THREADED
107
+ ssize_t ret = write(q->pipe_write, "0", 1); /* Wake up Ruby listener */
108
+
109
+ if (ret < 0)
133
110
  log_err("write to queue (%p) pipe failed!\n", q);
134
- }
111
+ #endif
112
+
135
113
  }
136
114
 
137
115
  // NOTE: the zkrb_event_t* returned *is* the same pointer that's part of the
@@ -182,8 +160,10 @@ void zkrb_signal(zkrb_queue_t *q) {
182
160
 
183
161
  global_mutex_lock();
184
162
 
163
+ #if THREADED
185
164
  if (!write(q->pipe_write, "0", 1)) /* Wake up Ruby listener */
186
165
  log_err("zkrb_signal: write to pipe failed, could not wake");
166
+ #endif
187
167
 
188
168
  global_mutex_unlock();
189
169
  }
@@ -200,10 +180,12 @@ zkrb_event_ll_t *zkrb_event_ll_t_alloc(void) {
200
180
  }
201
181
 
202
182
  zkrb_queue_t *zkrb_queue_alloc(void) {
203
- int pfd[2];
204
183
  zkrb_queue_t *rq = NULL;
205
184
 
185
+ #if THREADED
186
+ int pfd[2];
206
187
  check(pipe(pfd) == 0, "creating the signal pipe failed");
188
+ #endif
207
189
 
208
190
  rq = zk_malloc(sizeof(zkrb_queue_t));
209
191
  check_mem(rq);
@@ -214,8 +196,11 @@ zkrb_queue_t *zkrb_queue_alloc(void) {
214
196
  check_mem(rq->head);
215
197
 
216
198
  rq->tail = rq->head;
199
+
200
+ #if THREADED
217
201
  rq->pipe_read = pfd[0];
218
202
  rq->pipe_write = pfd[1];
203
+ #endif
219
204
 
220
205
  return rq;
221
206
 
@@ -233,8 +218,11 @@ void zkrb_queue_free(zkrb_queue_t *queue) {
233
218
  }
234
219
 
235
220
  zk_free(queue->head);
221
+
222
+ #if THREADED
236
223
  close(queue->pipe_read);
237
224
  close(queue->pipe_write);
225
+ #endif
238
226
 
239
227
  zk_free(queue);
240
228
  }
@@ -268,21 +256,26 @@ void zkrb_event_free(zkrb_event_t *event) {
268
256
  case ZKRB_STRINGS: {
269
257
  struct zkrb_strings_completion *strings_ctx = event->completion.strings_completion;
270
258
  int k;
271
- if (strings_ctx->values)
272
- for (k = 0; k < strings_ctx->values->count; ++k) zk_free(strings_ctx->values->data[k]);
273
- zk_free(strings_ctx->values);
259
+ if (strings_ctx->values) {
260
+ for (k = 0; k < strings_ctx->values->count; ++k) {
261
+ zk_free(strings_ctx->values->data[k]);
262
+ }
263
+ zk_free(strings_ctx->values);
264
+ }
274
265
  zk_free(strings_ctx);
275
266
  break;
276
267
  }
277
268
  case ZKRB_STRINGS_STAT: {
278
269
  struct zkrb_strings_stat_completion *strings_stat_ctx = event->completion.strings_stat_completion;
279
270
  int k;
280
- if (strings_stat_ctx->values)
281
- for (k = 0; k < strings_stat_ctx->values->count; ++k) zk_free(strings_stat_ctx->values->data[k]);
282
- zk_free(strings_stat_ctx->values);
271
+ if (strings_stat_ctx->values) {
272
+ for (k = 0; k < strings_stat_ctx->values->count; ++k) {
273
+ zk_free(strings_stat_ctx->values->data[k]);
274
+ }
275
+ zk_free(strings_stat_ctx->values);
276
+ }
283
277
 
284
- if (strings_stat_ctx->stat)
285
- zk_free(strings_stat_ctx->stat);
278
+ if (strings_stat_ctx->stat) zk_free(strings_stat_ctx->stat);
286
279
  zk_free(strings_stat_ctx);
287
280
  break;
288
281
  }
data/ext/zkrb.c CHANGED
@@ -107,16 +107,22 @@ typedef enum {
107
107
  } zkrb_call_type;
108
108
 
109
109
  inline static const char* call_type_to_str(zkrb_call_type ct) {
110
+ const char *rv = NULL;
110
111
  switch (ct) {
111
112
  case SYNC:
112
- return "SYNC";
113
+ rv="SYNC";
114
+ break;
113
115
  case ASYNC:
114
- return "ASYNC";
116
+ rv="ASYNC";
117
+ break;
115
118
  case SYNC_WATCH:
116
- return "SYNC_WATCH";
119
+ rv="SYNC_WATCH";
120
+ break;
117
121
  case ASYNC_WATCH:
118
- return "ASYNC_WATCH";
122
+ rv="ASYNC_WATCH";
123
+ break;
119
124
  }
125
+ return rv;
120
126
  }
121
127
 
122
128
  inline static void assert_valid_params(VALUE reqid, VALUE path) {
@@ -167,6 +173,17 @@ static void hexbufify(char *dest, const char *src, int len) {
167
173
  }
168
174
  }
169
175
 
176
+ inline static int we_are_forked(zkrb_instance_data_t *zk) {
177
+ int rv=0;
178
+
179
+ if ((!!zk) && (zk->orig_pid != getpid())) {
180
+ rv=1;
181
+ }
182
+
183
+ return rv;
184
+ }
185
+
186
+
170
187
  static int destroy_zkrb_instance(zkrb_instance_data_t* zk) {
171
188
  int rv = ZOK;
172
189
 
@@ -177,23 +194,23 @@ static int destroy_zkrb_instance(zkrb_instance_data_t* zk) {
177
194
  /* Note that after zookeeper_close() returns, ZK handle is invalid */
178
195
  zkrb_debug("obj_id: %lx, calling zookeeper_close", zk->object_id);
179
196
 
180
- if (zk->orig_pid != getpid()) {
197
+ if (we_are_forked(zk)) {
181
198
  zkrb_debug("FORK DETECTED! orig_pid: %d, current pid: %d, "
182
199
  "using socket-closing hack before zookeeper_close", zk->orig_pid, getpid());
183
200
 
184
201
  int fd = ((int *)zk->zh)[0]; // nasty, brutish, and wonderfully effective hack (see above)
185
202
  close(fd);
203
+
186
204
  }
187
205
 
188
206
  rv = zookeeper_close(zk->zh);
189
207
 
190
- zkrb_debug("obj_id: %lx, zookeeper_close returned %d", zk->object_id, rv);
208
+ zkrb_debug("obj_id: %lx, zookeeper_close returned %d, calling context: %p", zk->object_id, rv, ctx);
191
209
  zkrb_calling_context_free((zkrb_calling_context *) ctx);
192
210
  }
193
211
 
194
212
  zk->zh = NULL;
195
213
 
196
- // [wickman] TODO: fire off warning if queue is not empty
197
214
  if (zk->queue) {
198
215
  zkrb_debug("obj_id: %lx, freeing queue pointer: %p", zk->object_id, zk->queue);
199
216
  zkrb_queue_free(zk->queue);
@@ -222,7 +239,7 @@ static void print_zkrb_instance_data(zkrb_instance_data_t* ptr) {
222
239
 
223
240
  inline static void zkrb_debug_clientid_t(const clientid_t *cid) {
224
241
  int pass_len = sizeof(cid->passwd);
225
- int hex_len = 2 * pass_len;
242
+ int hex_len = 2 * pass_len + 1;
226
243
  char buf[hex_len];
227
244
  hexbufify(buf, cid->passwd, pass_len);
228
245
 
@@ -230,8 +247,8 @@ inline static void zkrb_debug_clientid_t(const clientid_t *cid) {
230
247
  }
231
248
 
232
249
  static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
233
- VALUE hostPort;
234
- VALUE options;
250
+ VALUE hostPort=Qnil;
251
+ VALUE options=Qnil;
235
252
 
236
253
  rb_scan_args(argc, argv, "11", &hostPort, &options);
237
254
 
@@ -249,7 +266,7 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
249
266
  zoo_set_debug_level(0); // no log messages
250
267
  } else {
251
268
  Check_Type(log_level, T_FIXNUM);
252
- zoo_set_debug_level((int)log_level);
269
+ zoo_set_debug_level(FIX2INT(log_level));
253
270
  }
254
271
 
255
272
  VALUE data;
@@ -270,12 +287,12 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
270
287
 
271
288
  zk_local_ctx->zh =
272
289
  zookeeper_init(
273
- RSTRING_PTR(hostPort),
274
- zkrb_state_callback,
275
- session_timeout_msec(self),
276
- &zk_local_ctx->myid,
277
- ctx,
278
- 0);
290
+ RSTRING_PTR(hostPort), // const char *host
291
+ zkrb_state_callback, // watcher_fn
292
+ session_timeout_msec(self), // recv_timeout
293
+ &zk_local_ctx->myid, // cilentid_t
294
+ ctx, // void *context
295
+ 0); // flags
279
296
 
280
297
  zkrb_debug("method_zkrb_init, zk_local_ctx: %p, zh: %p, queue: %p, calling_ctx: %p",
281
298
  zk_local_ctx, zk_local_ctx->zh, zk_local_ctx->queue, ctx);
@@ -399,12 +416,14 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
399
416
  if (data != Qnil) Check_Type(data, T_STRING);
400
417
  Check_Type(flags, T_FIXNUM);
401
418
  const char *data_ptr = (data == Qnil) ? NULL : RSTRING_PTR(data);
402
- size_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
419
+ ssize_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
403
420
 
404
421
  struct ACL_vector *aclptr = NULL;
405
422
  if (acls != Qnil) { aclptr = zkrb_ruby_to_aclvector(acls); }
406
423
  char realpath[16384];
407
424
 
425
+ int invalid_call_type=0;
426
+
408
427
  int rc;
409
428
  switch (call_type) {
410
429
 
@@ -420,7 +439,7 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
420
439
  break;
421
440
 
422
441
  default:
423
- raise_invalid_call_type_err(call_type);
442
+ invalid_call_type=1;
424
443
  break;
425
444
  }
426
445
 
@@ -429,6 +448,8 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
429
448
  free(aclptr);
430
449
  }
431
450
 
451
+ if (invalid_call_type) raise_invalid_call_type_err(call_type);
452
+
432
453
  output = rb_ary_new();
433
454
  rb_ary_push(output, INT2FIX(rc));
434
455
  if (IS_SYNC(call_type) && rc == ZOK) {
@@ -472,9 +493,13 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
472
493
  int data_len = MAX_ZNODE_SIZE;
473
494
  struct Stat stat;
474
495
 
475
- char * data = xmalloc(MAX_ZNODE_SIZE); /* ugh */
496
+ char * data = NULL;
497
+ if (IS_SYNC(call_type)) {
498
+ data = malloc(MAX_ZNODE_SIZE); /* ugh */
499
+ memset(data, 0, sizeof(data));
500
+ }
476
501
 
477
- int rc;
502
+ int rc, invalid_call_type=0;
478
503
 
479
504
  switch (call_type) {
480
505
 
@@ -500,7 +525,8 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
500
525
  break;
501
526
 
502
527
  default:
503
- raise_invalid_call_type_err(call_type);
528
+ invalid_call_type=1;
529
+ goto cleanup;
504
530
  break;
505
531
  }
506
532
 
@@ -514,7 +540,9 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
514
540
  rb_ary_push(output, zkrb_stat_to_rarray(&stat));
515
541
  }
516
542
 
517
- xfree(data);
543
+ cleanup:
544
+ free(data);
545
+ if (invalid_call_type) raise_invalid_call_type_err(call_type);
518
546
  return output;
519
547
  }
520
548
 
@@ -527,9 +555,9 @@ static VALUE method_set(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE a
527
555
  if (data != Qnil) Check_Type(data, T_STRING);
528
556
 
529
557
  const char *data_ptr = (data == Qnil) ? NULL : RSTRING_PTR(data);
530
- size_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
558
+ ssize_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
531
559
 
532
- int rc;
560
+ int rc=ZOK;
533
561
  switch (call_type) {
534
562
 
535
563
  #ifdef THREADED
@@ -561,7 +589,7 @@ static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VAL
561
589
 
562
590
  struct ACL_vector * aclptr = zkrb_ruby_to_aclvector(acls);
563
591
 
564
- int rc;
592
+ int rc=ZOK, invalid_call_type=0;
565
593
  switch (call_type) {
566
594
 
567
595
  #ifdef THREADED
@@ -575,13 +603,15 @@ static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VAL
575
603
  break;
576
604
 
577
605
  default:
578
- raise_invalid_call_type_err(call_type);
606
+ invalid_call_type=1;
579
607
  break;
580
608
  }
581
609
 
582
610
  deallocate_ACL_vector(aclptr);
583
611
  free(aclptr);
584
612
 
613
+ if (invalid_call_type) raise_invalid_call_type_err(call_type);
614
+
585
615
  return INT2FIX(rc);
586
616
  }
587
617
 
@@ -592,7 +622,7 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
592
622
  struct ACL_vector acls;
593
623
  struct Stat stat;
594
624
 
595
- int rc;
625
+ int rc=ZOK;
596
626
  switch (call_type) {
597
627
 
598
628
  #ifdef THREADED
@@ -692,12 +722,14 @@ static VALUE method_zkrb_get_next_event_st(VALUE self) {
692
722
  rval = zkrb_event_to_ruby(event);
693
723
  zkrb_event_free(event);
694
724
 
725
+ #if THREADED
695
726
  int fd = zk->queue->pipe_read;
696
727
 
697
728
  // we don't care in this case. this is just until i can remove the self
698
729
  // pipe from the queue
699
730
  char b[128];
700
731
  while(read(fd, b, sizeof(b)) == sizeof(b)){}
732
+ #endif
701
733
  }
702
734
 
703
735
  return rval;
@@ -721,7 +753,6 @@ inline static int get_self_pipe_read_fd(VALUE self) {
721
753
  #endif
722
754
  }
723
755
 
724
-
725
756
  static VALUE method_zkrb_iterate_event_loop(VALUE self) {
726
757
  FETCH_DATA_PTR(self, zk);
727
758
 
@@ -730,7 +761,7 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
730
761
 
731
762
  int fd=0, interest=0, events=0, rc=0, maxfd=0;
732
763
  struct timeval tv;
733
-
764
+
734
765
  zookeeper_interest(zk->zh, &fd, &interest, &tv);
735
766
 
736
767
  if (fd != -1) {
@@ -767,9 +798,12 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
767
798
 
768
799
  // we got woken up by the self-pipe
769
800
  if (FD_ISSET(pipe_r_fd, &rfds)) {
770
- // flush the pipe (from mt_adaptor.c)
801
+ // one event has awoken us, so we clear one event from the pipe
771
802
  char b[1];
772
- read(pipe_r_fd, b, 1); // one event has awoken us, so we clear one event from the pipe
803
+
804
+ if (read(pipe_r_fd, b, 1) < 0) {
805
+ rb_raise(rb_eRuntimeError, "read from pipe failed: %s", clean_errno());
806
+ }
773
807
  }
774
808
 
775
809
  rc = zookeeper_process(zk->zh, events);
@@ -793,18 +827,11 @@ static VALUE method_has_events(VALUE self) {
793
827
  return rb_event;
794
828
  }
795
829
 
796
-
797
- // wake up the event loop, used when shutting down
798
- #if 0
799
- static VALUE method_wake_event_loop_bang(VALUE self) {
800
- FETCH_DATA_PTR(self, zk);
801
-
802
- zkrb_debug_inst(self, "Waking event loop: %p", zk->queue);
803
- zkrb_signal(zk->queue);
804
-
830
+ static VALUE method_zoo_set_log_level(VALUE self, VALUE level) {
831
+ Check_Type(level, T_FIXNUM);
832
+ zoo_set_debug_level(FIX2INT(level));
805
833
  return Qnil;
806
- };
807
- #endif
834
+ }
808
835
 
809
836
  static VALUE method_close_handle(VALUE self) {
810
837
  FETCH_DATA_PTR(self, zk);
@@ -846,12 +873,6 @@ static VALUE method_recv_timeout(VALUE self) {
846
873
  return INT2NUM(zoo_recv_timeout(zk->zh));
847
874
  }
848
875
 
849
- /*static VALUE method_client_id(VALUE self) {*/
850
- /* FETCH_DATA_PTR(self, zk);*/
851
- /* const clientid_t *id = zoo_client_id(zk->zh);*/
852
- /* return UINT2NUM(id->client_id);*/
853
- /*}*/
854
-
855
876
  // returns a CZookeeper::ClientId object with the values set for session_id and passwd
856
877
  static VALUE method_client_id(VALUE self) {
857
878
  FETCH_DATA_PTR(self, zk);
@@ -859,7 +880,7 @@ static VALUE method_client_id(VALUE self) {
859
880
  const clientid_t *cid = zoo_client_id(zk->zh);
860
881
 
861
882
  if (strlen(cid->passwd) != 16) {
862
- zkrb_debug("passwd is not null-termniated");
883
+ zkrb_debug("passwd is not null-terminated");
863
884
  } else {
864
885
  hexbufify(buf, cid->passwd, 16);
865
886
  zkrb_debug("password in hex is: %s", buf);
@@ -910,6 +931,8 @@ static void zkrb_define_methods(void) {
910
931
  rb_define_method(CZookeeper, "zkrb_set_acl", method_set_acl, 5);
911
932
  rb_define_method(CZookeeper, "zkrb_get_acl", method_get_acl, 3);
912
933
 
934
+ rb_define_singleton_method(CZookeeper, "zoo_set_log_level", method_zoo_set_log_level, 1);
935
+
913
936
  DEFINE_METHOD(client_id, 0);
914
937
  DEFINE_METHOD(close_handle, 0);
915
938
  DEFINE_METHOD(deterministic_conn_order, 1);
@@ -1,4 +1,4 @@
1
1
  module Zookeeper
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.1'
3
3
  DRIVER_VERSION = '3.3.5'
4
4
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zookeeper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 0
10
- version: 1.1.0
9
+ - 1
10
+ version: 1.1.1
11
11
  platform: java
12
12
  authors:
13
13
  - Phillip Pearson
@@ -20,7 +20,7 @@ autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
22
 
23
- date: 2012-05-14 00:00:00 Z
23
+ date: 2012-05-15 00:00:00 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: backports
@@ -186,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
186
  requirements: []
187
187
 
188
188
  rubyforge_project:
189
- rubygems_version: 1.8.15
189
+ rubygems_version: 1.8.24
190
190
  signing_key:
191
191
  specification_version: 3
192
192
  summary: Apache ZooKeeper driver for Rubies