zookeeper 0.3.2 → 0.4.0

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,5 @@
1
+ v0.4.0. More attr-readers (StarvingMarvin) and 1.9 compatibility (tsuraan)
2
+
1
3
  v0.3.2. Handle close, closed connections and expired sessions a little more gracefully.
2
4
 
3
5
  v0.3.1. ACL bugfix.
data/Manifest CHANGED
@@ -1,7 +1,9 @@
1
1
  CHANGELOG
2
2
  LICENSE
3
+ Manifest
3
4
  README
4
5
  Rakefile
6
+ examples/cloud_config.rb
5
7
  ext/extconf.rb
6
8
  ext/zkc-3.3.1.tar.gz
7
9
  ext/zookeeper_c.c
@@ -13,4 +15,9 @@ lib/zookeeper/callbacks.rb
13
15
  lib/zookeeper/constants.rb
14
16
  lib/zookeeper/exceptions.rb
15
17
  lib/zookeeper/stat.rb
16
- Manifest
18
+ test/test_basic.rb
19
+ test/test_callback1.rb
20
+ test/test_close.rb
21
+ test/test_esoteric.rb
22
+ test/test_watcher1.rb
23
+ test/test_watcher2.rb
@@ -0,0 +1,125 @@
1
+ require "rubygems"
2
+ require "zookeeper"
3
+
4
+ # A basic cloud-based YAML config library. Ruby Zookeeper client example.
5
+ #
6
+ # If you pass in a file as 'zk:/foo.yml/blah' it will go out to zookeeper.
7
+ # Otherwise the file is assumed to be local. The yml file will get parsed
8
+ # and cached locally, and keys after the .yml get interpreted as keys into
9
+ # the YAML.
10
+ #
11
+ # e.g. get(zk:/config/service.yml/key1/key2/key3..) =>
12
+ # zk.get(:path => /config/service.yml)
13
+ # yaml <= YAML.parse(data)
14
+ # yaml[key1][key2][key3]...
15
+ #
16
+ # If keys are unspecified, it returns the parsed YAML as one big object
17
+ #
18
+ # TODO if staleness is set to 0, read in YAML immediately before next
19
+ # get(...)
20
+
21
+ class CloudConfig
22
+ class NodeNotFound < StandardError; end
23
+ class BadPathError < StandardError; end
24
+
25
+ DEFAULT_SERVERS = "localhost:2181"
26
+
27
+ def initialize(zkservers = DEFAULT_SERVERS, staleness = 15) # maximum allowed staleness in seconds
28
+ @staleness = staleness
29
+ @lock = Mutex.new
30
+ @zkservers = DEFAULT_SERVERS
31
+
32
+ # cache
33
+ @data = {}
34
+ @zkcb = Zookeeper::WatcherCallback.new { dirty_callback(@zkcb.context) }
35
+ @zk = nil
36
+ end
37
+
38
+ def get(node)
39
+ filename, keys = extract_filename(node)
40
+
41
+ # read(filename) is potentially a zk call, so do not hold the lock during the read
42
+ if @lock.synchronize { !@data.has_key?(filename) }
43
+ d = YAML.load(read(filename))
44
+ @lock.synchronize { @data[filename] = d }
45
+ end
46
+
47
+ # synchronized b/c we potentially have a background thread updating data nodes from zk
48
+ # if keys is empty, return the whole file, otherwise roll up the keys
49
+ @lock.synchronize {
50
+ keys.empty? ? @data[filename] : keys.inject(@data[filename]) { |hash, key| hash[key] }
51
+ }
52
+ end
53
+
54
+ # todo:
55
+ # factor get-and-watch into a different subsystem (so you can have
56
+ # polling stat() ops on local filesystem.)
57
+ def read(yaml)
58
+ # read yaml file and register watcher. if watcher fires, set up
59
+ # background thread to do read and update data.
60
+ if yaml.match(/^zk:/)
61
+ @zk ||= init_zk
62
+ yaml = yaml['zk:'.length..-1] # strip off zk: from zk:/config/path.yml
63
+ resp = get_and_register(yaml)
64
+
65
+ if resp[:rc] != Zookeeper::ZOK
66
+ @zk.unregister_watcher(resp[:req_id])
67
+ raise NodeNotFound
68
+ end
69
+
70
+ resp[:data]
71
+ else
72
+ raise NodeNotFound unless File.exists?(yaml)
73
+ File.read(yaml)
74
+ end
75
+ end
76
+
77
+ def extract_filename(node)
78
+ path_elements = node.split("/")
79
+
80
+ yamlindex = path_elements.map{ |x| x.match("\.yml$") != nil }.index(true)
81
+ raise BadPathError unless yamlindex
82
+
83
+ yamlname = path_elements[0..yamlindex].join '/'
84
+ yamlkeys = path_elements[(yamlindex+1)..-1]
85
+
86
+ return yamlname, yamlkeys
87
+ end
88
+
89
+ private
90
+ def init_zk
91
+ Zookeeper.new(@zkservers)
92
+ end
93
+
94
+ def get_and_register(znode)
95
+ @zk.get(:path => znode, :watcher => @zkcb,
96
+ :watcher_context => { :path => znode,
97
+ :wait => rand(@staleness) })
98
+ end
99
+
100
+ def dirty_callback(context)
101
+ path = context[:path]
102
+ wait = context[:wait]
103
+
104
+ # Fire off a background update that waits a randomized period of time up
105
+ # to @staleness seconds.
106
+ Thread.new do
107
+ sleep wait
108
+ background_update(path)
109
+ end
110
+ end
111
+
112
+ def background_update(zkpath)
113
+ # do a synchronous get/register a new watcher
114
+ resp = get_and_register(zkpath)
115
+ if resp[:rc] != Zookeeper::ZOK
116
+ # puts "Unable to read #{zkpath} from Zookeeper!" @logger.error
117
+ zk.unregister_watcher(resp[:req_id])
118
+ else
119
+ # puts "Updating data."
120
+ d = YAML.load(resp[:data])
121
+ @lock.synchronize { @data["zk:#{zkpath}"] = d }
122
+ end
123
+ end
124
+ end
125
+
data/ext/zookeeper_c.c CHANGED
@@ -75,7 +75,7 @@ static VALUE method_init(VALUE self, VALUE hostPort) {
75
75
 
76
76
  zk_local_ctx->zh =
77
77
  zookeeper_init(
78
- RSTRING(hostPort)->ptr,
78
+ RSTRING_PTR(hostPort),
79
79
  zkrb_state_callback,
80
80
  10000,
81
81
  &zk_local_ctx->myid,
@@ -127,19 +127,19 @@ static VALUE method_get_children(VALUE self, VALUE reqid, VALUE path, VALUE asyn
127
127
  int rc;
128
128
  switch (call_type) {
129
129
  case SYNC:
130
- rc = zoo_get_children2(zk->zh, RSTRING(path)->ptr, 0, &strings, &stat);
130
+ rc = zoo_get_children2(zk->zh, RSTRING_PTR(path), 0, &strings, &stat);
131
131
  break;
132
132
 
133
133
  case SYNC_WATCH:
134
- rc = zoo_wget_children2(zk->zh, RSTRING(path)->ptr, zkrb_state_callback, watch_ctx, &strings, &stat);
134
+ rc = zoo_wget_children2(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, &strings, &stat);
135
135
  break;
136
136
 
137
137
  case ASYNC:
138
- rc = zoo_aget_children2(zk->zh, RSTRING(path)->ptr, 0, zkrb_strings_stat_callback, data_ctx);
138
+ rc = zoo_aget_children2(zk->zh, RSTRING_PTR(path), 0, zkrb_strings_stat_callback, data_ctx);
139
139
  break;
140
140
 
141
141
  case ASYNC_WATCH:
142
- rc = zoo_awget_children2(zk->zh, RSTRING(path)->ptr, zkrb_state_callback, watch_ctx, zkrb_strings_stat_callback, data_ctx);
142
+ rc = zoo_awget_children2(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, zkrb_strings_stat_callback, data_ctx);
143
143
  break;
144
144
  }
145
145
 
@@ -160,19 +160,19 @@ static VALUE method_exists(VALUE self, VALUE reqid, VALUE path, VALUE async, VAL
160
160
  int rc;
161
161
  switch (call_type) {
162
162
  case SYNC:
163
- rc = zoo_exists(zk->zh, RSTRING(path)->ptr, 0, &stat);
163
+ rc = zoo_exists(zk->zh, RSTRING_PTR(path), 0, &stat);
164
164
  break;
165
165
 
166
166
  case SYNC_WATCH:
167
- rc = zoo_wexists(zk->zh, RSTRING(path)->ptr, zkrb_state_callback, watch_ctx, &stat);
167
+ rc = zoo_wexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, &stat);
168
168
  break;
169
169
 
170
170
  case ASYNC:
171
- rc = zoo_aexists(zk->zh, RSTRING(path)->ptr, 0, zkrb_stat_callback, data_ctx);
171
+ rc = zoo_aexists(zk->zh, RSTRING_PTR(path), 0, zkrb_stat_callback, data_ctx);
172
172
  break;
173
173
 
174
174
  case ASYNC_WATCH:
175
- rc = zoo_awexists(zk->zh, RSTRING(path)->ptr, zkrb_state_callback, watch_ctx, zkrb_stat_callback, data_ctx);
175
+ rc = zoo_awexists(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, zkrb_stat_callback, data_ctx);
176
176
  break;
177
177
  }
178
178
 
@@ -191,8 +191,8 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
191
191
  struct Stat stat;
192
192
  if (data != Qnil) Check_Type(data, T_STRING);
193
193
  Check_Type(flags, T_FIXNUM);
194
- const char *data_ptr = (data == Qnil) ? NULL : RSTRING(data)->ptr;
195
- size_t data_len = (data == Qnil) ? -1 : RSTRING(data)->len;
194
+ const char *data_ptr = (data == Qnil) ? NULL : RSTRING_PTR(data);
195
+ size_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
196
196
 
197
197
  struct ACL_vector *aclptr = NULL;
198
198
  if (acls != Qnil) { aclptr = zkrb_ruby_to_aclvector(acls); }
@@ -201,11 +201,11 @@ static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALU
201
201
  int rc;
202
202
  switch (call_type) {
203
203
  case SYNC:
204
- rc = zoo_create(zk->zh, RSTRING(path)->ptr, data_ptr, data_len, aclptr, FIX2INT(flags), realpath, sizeof(realpath));
204
+ rc = zoo_create(zk->zh, RSTRING_PTR(path), data_ptr, data_len, aclptr, FIX2INT(flags), realpath, sizeof(realpath));
205
205
  if (aclptr != NULL) deallocate_ACL_vector(aclptr);
206
206
  break;
207
207
  case ASYNC:
208
- rc = zoo_acreate(zk->zh, RSTRING(path)->ptr, data_ptr, data_len, aclptr, FIX2INT(flags), zkrb_string_callback, data_ctx);
208
+ rc = zoo_acreate(zk->zh, RSTRING_PTR(path), data_ptr, data_len, aclptr, FIX2INT(flags), zkrb_string_callback, data_ctx);
209
209
  if (aclptr != NULL) deallocate_ACL_vector(aclptr);
210
210
  break;
211
211
  default:
@@ -230,10 +230,10 @@ static VALUE method_delete(VALUE self, VALUE reqid, VALUE path, VALUE version, V
230
230
  int rc = 0;
231
231
  switch (call_type) {
232
232
  case SYNC:
233
- rc = zoo_delete(zk->zh, RSTRING(path)->ptr, FIX2INT(version));
233
+ rc = zoo_delete(zk->zh, RSTRING_PTR(path), FIX2INT(version));
234
234
  break;
235
235
  case ASYNC:
236
- rc = zoo_adelete(zk->zh, RSTRING(path)->ptr, FIX2INT(version), zkrb_void_callback, data_ctx);
236
+ rc = zoo_adelete(zk->zh, RSTRING_PTR(path), FIX2INT(version), zkrb_void_callback, data_ctx);
237
237
  break;
238
238
  default:
239
239
  /* TODO(wickman) raise proper argument error */
@@ -258,19 +258,19 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
258
258
 
259
259
  switch (call_type) {
260
260
  case SYNC:
261
- rc = zoo_get(zk->zh, RSTRING(path)->ptr, 0, data, &data_len, &stat);
261
+ rc = zoo_get(zk->zh, RSTRING_PTR(path), 0, data, &data_len, &stat);
262
262
  break;
263
263
 
264
264
  case SYNC_WATCH:
265
- rc = zoo_wget(zk->zh, RSTRING(path)->ptr, zkrb_state_callback, watch_ctx, data, &data_len, &stat);
265
+ rc = zoo_wget(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, data, &data_len, &stat);
266
266
  break;
267
267
 
268
268
  case ASYNC:
269
- rc = zoo_aget(zk->zh, RSTRING(path)->ptr, 0, zkrb_data_callback, data_ctx);
269
+ rc = zoo_aget(zk->zh, RSTRING_PTR(path), 0, zkrb_data_callback, data_ctx);
270
270
  break;
271
271
 
272
272
  case ASYNC_WATCH:
273
- rc = zoo_awget(zk->zh, RSTRING(path)->ptr, zkrb_state_callback, watch_ctx, zkrb_data_callback, data_ctx);
273
+ rc = zoo_awget(zk->zh, RSTRING_PTR(path), zkrb_state_callback, watch_ctx, zkrb_data_callback, data_ctx);
274
274
  break;
275
275
  }
276
276
 
@@ -291,16 +291,16 @@ static VALUE method_set(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE a
291
291
 
292
292
  struct Stat stat;
293
293
  if (data != Qnil) Check_Type(data, T_STRING);
294
- const char *data_ptr = (data == Qnil) ? NULL : RSTRING(data)->ptr;
295
- size_t data_len = (data == Qnil) ? -1 : RSTRING(data)->len;
294
+ const char *data_ptr = (data == Qnil) ? NULL : RSTRING_PTR(data);
295
+ size_t data_len = (data == Qnil) ? -1 : RSTRING_LEN(data);
296
296
 
297
297
  int rc;
298
298
  switch (call_type) {
299
299
  case SYNC:
300
- rc = zoo_set2(zk->zh, RSTRING(path)->ptr, data_ptr, data_len, FIX2INT(version), &stat);
300
+ rc = zoo_set2(zk->zh, RSTRING_PTR(path), data_ptr, data_len, FIX2INT(version), &stat);
301
301
  break;
302
302
  case ASYNC:
303
- rc = zoo_aset(zk->zh, RSTRING(path)->ptr, data_ptr, data_len, FIX2INT(version),
303
+ rc = zoo_aset(zk->zh, RSTRING_PTR(path), data_ptr, data_len, FIX2INT(version),
304
304
  zkrb_stat_callback, data_ctx);
305
305
  break;
306
306
  default:
@@ -325,11 +325,11 @@ static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VAL
325
325
  int rc;
326
326
  switch (call_type) {
327
327
  case SYNC:
328
- rc = zoo_set_acl(zk->zh, RSTRING(path)->ptr, FIX2INT(version), aclptr);
328
+ rc = zoo_set_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr);
329
329
  deallocate_ACL_vector(aclptr);
330
330
  break;
331
331
  case ASYNC:
332
- rc = zoo_aset_acl(zk->zh, RSTRING(path)->ptr, FIX2INT(version), aclptr, zkrb_void_callback, data_ctx);
332
+ rc = zoo_aset_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr, zkrb_void_callback, data_ctx);
333
333
  deallocate_ACL_vector(aclptr);
334
334
  break;
335
335
  default:
@@ -351,10 +351,10 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
351
351
  int rc;
352
352
  switch (call_type) {
353
353
  case SYNC:
354
- rc = zoo_get_acl(zk->zh, RSTRING(path)->ptr, &acls, &stat);
354
+ rc = zoo_get_acl(zk->zh, RSTRING_PTR(path), &acls, &stat);
355
355
  break;
356
356
  case ASYNC:
357
- rc = zoo_aget_acl(zk->zh, RSTRING(path)->ptr, zkrb_acl_callback, data_ctx);
357
+ rc = zoo_aget_acl(zk->zh, RSTRING_PTR(path), zkrb_acl_callback, data_ctx);
358
358
  break;
359
359
  default:
360
360
  /* TODO(wickman) raise proper argument error */
data/ext/zookeeper_lib.c CHANGED
@@ -411,7 +411,7 @@ struct ACL_vector * zkrb_ruby_to_aclvector(VALUE acl_ary) {
411
411
  Check_Type(acl_ary, T_ARRAY);
412
412
 
413
413
  struct ACL_vector *v = malloc(sizeof(struct ACL_vector));
414
- allocate_ACL_vector(v, RARRAY(acl_ary)->len);
414
+ allocate_ACL_vector(v, RARRAY_LEN(acl_ary));
415
415
 
416
416
  int k;
417
417
  for (k = 0; k < v->count; ++k) {
@@ -442,17 +442,17 @@ struct Id zkrb_ruby_to_id(VALUE rubyid) {
442
442
  VALUE ident = rb_iv_get(rubyid, "@id");
443
443
 
444
444
  if (scheme != Qnil) {
445
- id.scheme = malloc(RSTRING(scheme)->len + 1);
446
- strncpy(id.scheme, RSTRING(scheme)->ptr, RSTRING(scheme)->len);
447
- id.scheme[RSTRING(scheme)->len] = '\0';
445
+ id.scheme = malloc(RSTRING_LEN(scheme) + 1);
446
+ strncpy(id.scheme, RSTRING_PTR(scheme), RSTRING_LEN(scheme));
447
+ id.scheme[RSTRING_LEN(scheme)] = '\0';
448
448
  } else {
449
449
  id.scheme = NULL;
450
450
  }
451
451
 
452
452
  if (ident != Qnil) {
453
- id.id = malloc(RSTRING(ident)->len + 1);
454
- strncpy(id.id, RSTRING(ident)->ptr, RSTRING(ident)->len);
455
- id.id[RSTRING(ident)->len] = '\0';
453
+ id.id = malloc(RSTRING_LEN(ident) + 1);
454
+ strncpy(id.id, RSTRING_PTR(ident), RSTRING_LEN(ident));
455
+ id.id[RSTRING_LEN(ident)] = '\0';
456
456
  } else {
457
457
  id.id = NULL;
458
458
  }
data/ext/zookeeper_lib.h CHANGED
@@ -11,6 +11,16 @@
11
11
  #define ZK_FALSE 0
12
12
  #define ZKRB_GLOBAL_REQ -1
13
13
 
14
+ #ifndef RSTRING_LEN
15
+ # define RSTRING_LEN(x) RSTRING(x)->len
16
+ #endif
17
+ #ifndef RSTRING_PTR
18
+ # define RSTRING_PTR(x) RSTRING(x)->ptr
19
+ #endif
20
+ #ifndef RARRAY_LEN
21
+ # define RARRAY_LEN(x) RARRAY(x)->len
22
+ #endif
23
+
14
24
  extern int ZKRBDebugging;
15
25
 
16
26
  struct zkrb_data_completion {
@@ -1,6 +1,6 @@
1
1
  module ZookeeperStat
2
2
  class Stat
3
- attr_reader :version, :exists
3
+ attr_reader :version, :exists, :czxid, :mzxid, :ctime, :mtime, :cverzion, :aversion, :ephemeralOwner, :dataLength, :numChildren, :pzxid
4
4
  def initialize(val)
5
5
  @exists = !!val
6
6
  @czxid, @mzxid, @ctime, @mtime, @version, @cversion, @aversion,
data/zookeeper.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{zookeeper}
5
- s.version = "0.3.2"
5
+ s.version = "0.4.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Phillip Pearson, Eric Maland, Evan Weaver, Brian Wickman"]
9
- s.date = %q{2010-08-17}
9
+ s.date = %q{2010-12-01}
10
10
  s.description = %q{An interface to the Zookeeper distributed configuration server.}
11
11
  s.email = %q{}
12
12
  s.extensions = ["ext/extconf.rb"]
13
13
  s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "ext/zookeeper_c.c", "lib/zookeeper.rb"]
14
- s.files = ["CHANGELOG", "LICENSE", "README", "Rakefile", "ext/extconf.rb", "ext/zkc-3.3.1.tar.gz", "ext/zookeeper_c.c", "ext/zookeeper_lib.c", "ext/zookeeper_lib.h", "lib/zookeeper.rb", "lib/zookeeper/acls.rb", "lib/zookeeper/callbacks.rb", "lib/zookeeper/constants.rb", "lib/zookeeper/exceptions.rb", "lib/zookeeper/stat.rb", "Manifest", "zookeeper.gemspec", "test/test_basic.rb", "test/test_callback1.rb", "test/test_close.rb", "test/test_esoteric.rb", "test/test_watcher1.rb", "test/test_watcher2.rb"]
14
+ s.files = ["CHANGELOG", "LICENSE", "README", "Rakefile", "examples/cloud_config.rb", "ext/extconf.rb", "ext/zkc-3.3.1.tar.gz", "ext/zookeeper_c.c", "ext/zookeeper_lib.c", "ext/zookeeper_lib.h", "lib/zookeeper.rb", "lib/zookeeper/acls.rb", "lib/zookeeper/callbacks.rb", "lib/zookeeper/constants.rb", "lib/zookeeper/exceptions.rb", "lib/zookeeper/stat.rb", "test/test_basic.rb", "test/test_callback1.rb", "test/test_close.rb", "test/test_esoteric.rb", "test/test_watcher1.rb", "test/test_watcher2.rb", "Manifest", "zookeeper.gemspec"]
15
15
  s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/zookeeper/}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Zookeeper", "--main", "README"]
17
17
  s.require_paths = ["lib", "ext"]
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: 23
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 2
10
- version: 0.3.2
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Phillip Pearson, Eric Maland, Evan Weaver, Brian Wickman
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-17 00:00:00 -07:00
18
+ date: 2010-12-01 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -36,6 +36,7 @@ files:
36
36
  - LICENSE
37
37
  - README
38
38
  - Rakefile
39
+ - examples/cloud_config.rb
39
40
  - ext/extconf.rb
40
41
  - ext/zkc-3.3.1.tar.gz
41
42
  - ext/zookeeper_c.c
@@ -47,14 +48,14 @@ files:
47
48
  - lib/zookeeper/constants.rb
48
49
  - lib/zookeeper/exceptions.rb
49
50
  - lib/zookeeper/stat.rb
50
- - Manifest
51
- - zookeeper.gemspec
52
51
  - test/test_basic.rb
53
52
  - test/test_callback1.rb
54
53
  - test/test_close.rb
55
54
  - test/test_esoteric.rb
56
55
  - test/test_watcher1.rb
57
56
  - test/test_watcher2.rb
57
+ - Manifest
58
+ - zookeeper.gemspec
58
59
  has_rdoc: true
59
60
  homepage: http://blog.evanweaver.com/files/doc/fauna/zookeeper/
60
61
  licenses: []