zookeeper 0.3.0 → 0.3.2

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,5 +1,8 @@
1
+ v0.3.2. Handle close, closed connections and expired sessions a little more gracefully.
1
2
 
2
- v0.3.0. Wickman's rewrite.
3
+ v0.3.1. ACL bugfix.
4
+
5
+ v0.3.0. Wickman's rewrite, breaks dependencies from myelin/emaland port.
3
6
 
4
7
  v0.2.2. Fix compatibility with stock Leopard fat-binary Ruby.
5
8
 
data/Manifest CHANGED
@@ -1,9 +1,7 @@
1
1
  CHANGELOG
2
2
  LICENSE
3
- Manifest
4
3
  README
5
4
  Rakefile
6
- examples/cloud_config.rb
7
5
  ext/extconf.rb
8
6
  ext/zkc-3.3.1.tar.gz
9
7
  ext/zookeeper_c.c
@@ -15,8 +13,4 @@ lib/zookeeper/callbacks.rb
15
13
  lib/zookeeper/constants.rb
16
14
  lib/zookeeper/exceptions.rb
17
15
  lib/zookeeper/stat.rb
18
- test/test_basic.rb
19
- test/test_callback1.rb
20
- test/test_esoteric.rb
21
- test/test_watcher1.rb
22
- test/test_watcher2.rb
16
+ Manifest
data/README CHANGED
@@ -4,14 +4,10 @@ An interface to the Zookeeper distributed configuration server.
4
4
 
5
5
  == License
6
6
 
7
- <<<<<<< HEAD
8
- Copyright 2008 Phillip Pearson, and 2010 Twitter, Inc. Licensed under the MIT License. See the included LICENSE file. Portions copyright 2008-2010 the Apache Software Foundation, licensed under the Apache 2 license, and used with permission.
9
- =======
10
7
  Copyright 2008 Phillip Pearson, and 2010 Twitter, Inc. Licensed under the
11
8
  MIT License. See the included LICENSE file. Portions copyright 2008-2010
12
9
  the Apache Software Foundation, licensed under the Apache 2 license, and
13
10
  used with permission.
14
- >>>>>>> wickman
15
11
 
16
12
  == Install
17
13
 
@@ -24,42 +20,6 @@ Connect to a server:
24
20
  require 'rubygems'
25
21
  require 'zookeeper'
26
22
  z = Zookeeper.new("localhost:2181")
27
- <<<<<<< HEAD
28
-
29
- Create, set and read nodes:
30
-
31
- z.create("/bacon", "text to be stored in the new node", 0)
32
- data, stat = z.get("/bacon")
33
- # => ["text to be stored in the new node"...]
34
-
35
- z.set("/bacon", "an entirely different line of text", stat.version)
36
- z.set("/bacon", "this won't work", stat.version)
37
- # CZookeeper::BadVersionError: expected version does not match actual version
38
-
39
- data, stat = z.get("/bacon")
40
- # => ["an entirely different line of text"...]
41
- z.delete("/bacon", stat.version)
42
-
43
- Create ephemeral and sequence nodes:
44
-
45
- z.create("/parent", "parent node", 0)
46
-
47
- z.create("/parent/test-",
48
- "an ordered ephemeral node",
49
- Zookeeper::EPHEMERAL | Zookeeper::SEQUENCE)
50
- # => "/parent/test-0"
51
-
52
- z.create("/parent/test-",
53
- "an ordered ephemeral node",
54
- Zookeeper::EPHEMERAL | Zookeeper::SEQUENCE)
55
- # => "/parent/test-1"
56
-
57
- Acquire locks:
58
-
59
- z.try_acquire "/parent/lock-", "content for the lock file" do |have_lock|
60
- puts have_lock ? "we have the lock" : "we don't have the lock"
61
- end
62
- =======
63
23
  z.get_children(:path => "/")
64
24
 
65
25
  == Idioms
@@ -80,4 +40,3 @@ Acquire locks:
80
40
  Calls take a dictionary of parameters. With the exception of set_acl, the
81
41
  only required parameter is :path. Each call returns a dictionary with at
82
42
  minimum two keys :req_id and :rc.
83
- >>>>>>> wickman
data/ext/extconf.rb CHANGED
@@ -33,7 +33,7 @@ Dir.chdir(HERE) do
33
33
  raise "'#{cmd}' failed" unless system(cmd)
34
34
 
35
35
  Dir.chdir(BUNDLE_PATH) do
36
- puts(cmd = "env CFLAGS='-fPIC #{$CFLAGS}' LDFLAGS='-fPIC #{$LDFLAGS}' ./configure --prefix=#{HERE} --without-cppunit --disable-shared --disable-dependency-tracking #{$EXTRA_CONF} 2>&1")
36
+ puts(cmd = "env CFLAGS='-fPIC #{$CFLAGS}' LDFLAGS='-fPIC #{$LDFLAGS}' ./configure --prefix=#{HERE} --without-cppunit --disable-dependency-tracking #{$EXTRA_CONF} 2>&1")
37
37
  raise "'#{cmd}' failed" unless system(cmd)
38
38
  puts(cmd = "make CXXFLAGS='#{$CXXFLAGS}' || true 2>&1")
39
39
  raise "'#{cmd}' failed" unless system(cmd)
data/ext/zookeeper_c.c CHANGED
@@ -38,14 +38,24 @@ typedef enum {
38
38
  #define IS_ASYNC(zkrbcall) ((zkrbcall)==ASYNC || (zkrbcall)==ASYNC_WATCH)
39
39
 
40
40
  static void free_zkrb_instance_data(struct zkrb_instance_data* ptr) {
41
- #warning [wickman] TODO: free queue
42
41
  #warning [wickman] TODO: fire off warning if queue is not empty
43
42
  if (ptr->zh && zoo_state(ptr->zh) == ZOO_CONNECTED_STATE) {
44
43
  zookeeper_close(ptr->zh);
45
44
  }
45
+ if (ptr->queue) zkrb_queue_free(ptr->queue);
46
+ ptr->queue = NULL;
46
47
  }
47
48
 
48
- static VALUE method_initialize(VALUE self, VALUE hostPort) {
49
+ static void print_zkrb_instance_data(struct zkrb_instance_data* ptr) {
50
+ fprintf(stderr, "zkrb_instance_data (%x) {\n", ptr);
51
+ fprintf(stderr, " zh = %x\n", ptr->zh);
52
+ fprintf(stderr, " { state = %d }\n", zoo_state(ptr->zh));
53
+ fprintf(stderr, " id = %llx\n", ptr->myid.client_id);
54
+ fprintf(stderr, " q = %x\n", ptr->queue);
55
+ fprintf(stderr, "}\n");
56
+ }
57
+
58
+ static VALUE method_init(VALUE self, VALUE hostPort) {
49
59
  Check_Type(hostPort, T_STRING);
50
60
 
51
61
  VALUE data;
@@ -96,11 +106,11 @@ static VALUE method_initialize(VALUE self, VALUE hostPort) {
96
106
  Data_Get_Struct(rb_iv_get(self, "@data"), struct zkrb_instance_data, zk); \
97
107
  zkrb_calling_context* cb_ctx = \
98
108
  (async != Qfalse && async != Qnil) ? \
99
- zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
109
+ zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
100
110
  NULL; \
101
111
  zkrb_calling_context* w_ctx = \
102
112
  (watch != Qfalse && watch != Qnil) ? \
103
- zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
113
+ zkrb_calling_context_alloc(NUM2LL(reqid), zk->queue) : \
104
114
  NULL; \
105
115
  int a = (async != Qfalse && async != Qnil); \
106
116
  int w = (watch != Qfalse && watch != Qnil); \
@@ -234,7 +244,6 @@ static VALUE method_delete(VALUE self, VALUE reqid, VALUE path, VALUE version, V
234
244
  return INT2FIX(rc);
235
245
  }
236
246
 
237
-
238
247
  #define MAX_ZNODE_SIZE 1048576
239
248
 
240
249
  static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE watch) {
@@ -246,6 +255,7 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
246
255
  struct Stat stat;
247
256
 
248
257
  int rc;
258
+
249
259
  switch (call_type) {
250
260
  case SYNC:
251
261
  rc = zoo_get(zk->zh, RSTRING(path)->ptr, 0, data, &data_len, &stat);
@@ -271,6 +281,7 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
271
281
  rb_ary_push(output, zkrb_stat_to_rarray(&stat));
272
282
  }
273
283
  free(data);
284
+
274
285
  return output;
275
286
  }
276
287
 
@@ -363,6 +374,7 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
363
374
 
364
375
  static VALUE method_get_next_event(VALUE self) {
365
376
  FETCH_DATA_PTR(self, zk);
377
+ if (zk->queue == NULL) return Qnil;
366
378
 
367
379
  zkrb_event_t *event = zkrb_dequeue(zk->queue);
368
380
  if (event == NULL) return Qnil;
@@ -374,6 +386,7 @@ static VALUE method_get_next_event(VALUE self) {
374
386
 
375
387
  static VALUE method_has_events(VALUE self) {
376
388
  FETCH_DATA_PTR(self, zk);
389
+ if (zk->queue == NULL) return Qfalse;
377
390
  return zkrb_peek(zk->queue) != NULL ? Qtrue : Qfalse;
378
391
  }
379
392
 
@@ -427,7 +440,7 @@ static void zkrb_define_methods(void) {
427
440
  #define DEFINE_CLASS_METHOD(method, args) { \
428
441
  rb_define_singleton_method(Zookeeper, #method, method_ ## method, args); }
429
442
 
430
- DEFINE_METHOD(initialize, 1);
443
+ DEFINE_METHOD(init, 1);
431
444
  DEFINE_METHOD(get_children, 4);
432
445
  DEFINE_METHOD(exists, 4);
433
446
  DEFINE_METHOD(create, 6);
data/ext/zookeeper_lib.c CHANGED
@@ -55,6 +55,15 @@ zkrb_queue_t *zkrb_queue_alloc(void) {
55
55
  return rq;
56
56
  }
57
57
 
58
+ void zkrb_queue_free(zkrb_queue_t *queue) {
59
+ if (queue == NULL) return;
60
+ zkrb_event_t *elt = NULL;
61
+ while ((elt = zkrb_dequeue(queue)) != NULL) {
62
+ zkrb_event_free(elt);
63
+ }
64
+ free(queue);
65
+ }
66
+
58
67
  zkrb_event_t *zkrb_event_alloc(void) {
59
68
  zkrb_event_t *rv = (zkrb_event_t *) malloc(sizeof(zkrb_event_t));
60
69
  return rv;
@@ -122,11 +131,11 @@ void zkrb_event_free(zkrb_event_t *event) {
122
131
  allocated on the proper thread stack */
123
132
  VALUE zkrb_event_to_ruby(zkrb_event_t *event) {
124
133
  VALUE hash = rb_hash_new();
125
-
134
+
126
135
  rb_hash_aset(hash, GET_SYM("req_id"), LL2NUM(event->req_id));
127
136
  if (event->type != ZKRB_WATCHER)
128
137
  rb_hash_aset(hash, GET_SYM("rc"), INT2FIX(event->rc));
129
-
138
+
130
139
  switch (event->type) {
131
140
  case ZKRB_DATA: {
132
141
  struct zkrb_data_completion *data_ctx = event->completion.data_completion;
@@ -435,6 +444,7 @@ struct Id zkrb_ruby_to_id(VALUE rubyid) {
435
444
  if (scheme != Qnil) {
436
445
  id.scheme = malloc(RSTRING(scheme)->len + 1);
437
446
  strncpy(id.scheme, RSTRING(scheme)->ptr, RSTRING(scheme)->len);
447
+ id.scheme[RSTRING(scheme)->len] = '\0';
438
448
  } else {
439
449
  id.scheme = NULL;
440
450
  }
@@ -442,6 +452,7 @@ struct Id zkrb_ruby_to_id(VALUE rubyid) {
442
452
  if (ident != Qnil) {
443
453
  id.id = malloc(RSTRING(ident)->len + 1);
444
454
  strncpy(id.id, RSTRING(ident)->ptr, RSTRING(ident)->len);
455
+ id.id[RSTRING(ident)->len] = '\0';
445
456
  } else {
446
457
  id.id = NULL;
447
458
  }
data/ext/zookeeper_lib.h CHANGED
@@ -87,10 +87,10 @@ typedef struct {
87
87
  } zkrb_queue_t;
88
88
 
89
89
  zkrb_queue_t * zkrb_queue_alloc(void);
90
+ void zkrb_queue_free(zkrb_queue_t *queue);
90
91
  zkrb_event_t * zkrb_event_alloc(void);
91
92
  void zkrb_event_free(zkrb_event_t *ptr);
92
93
 
93
-
94
94
  /* push/pop is a misnomer, this is a queue */
95
95
  void zkrb_enqueue(zkrb_queue_t *queue, zkrb_event_t *elt);
96
96
  zkrb_event_t * zkrb_peek(zkrb_queue_t *queue);
@@ -12,7 +12,7 @@ module ZookeeperCallbacks
12
12
  end
13
13
 
14
14
  def call(*args)
15
- puts "call passed #{args.inspect}"
15
+ # puts "call passed #{args.inspect}"
16
16
  @proc.call(*args)
17
17
  end
18
18
 
@@ -52,6 +52,7 @@ module ZookeeperExceptions
52
52
  class Closing < ZookeeperException; end
53
53
  class Nothing < ZookeeperException; end
54
54
  class SessionMoved < ZookeeperException; end
55
+ class ConnectionClosed < ZookeeperException; end # this is a Ruby client exception
55
56
 
56
57
  def self.by_code(code)
57
58
  case code
data/lib/zookeeper.rb CHANGED
@@ -23,28 +23,33 @@ class Zookeeper < CZookeeper
23
23
  ZOO_LOG_LEVEL_INFO = 3
24
24
  ZOO_LOG_LEVEL_DEBUG = 4
25
25
 
26
- def initialize(host, timeout = 10)
27
- @watcher_reqs = { ZKRB_GLOBAL_CB_REQ => { :watcher => get_default_global_watcher } }
28
- @completion_reqs = {}
29
- @req_mutex = Mutex.new
30
- @current_req_id = 1
31
- super(host)
32
-
26
+ def reopen(timeout = 10)
27
+ init(@host)
33
28
  if timeout > 0
34
29
  time_to_stop = Time.now + timeout
35
30
  until state == Zookeeper::ZOO_CONNECTED_STATE
36
31
  break if Time.now > time_to_stop
37
32
  sleep 0.1
38
33
  end
39
-
40
- return nil if state != Zookeeper::ZOO_CONNECTED_STATE
41
34
  end
35
+ # flushes all outstanding watcher reqs.
36
+ @watcher_reqs = { ZKRB_GLOBAL_CB_REQ => { :watcher => get_default_global_watcher } }
37
+ state
38
+ end
42
39
 
40
+ def initialize(host, timeout = 10)
41
+ @watcher_reqs = {}
42
+ @completion_reqs = {}
43
+ @req_mutex = Mutex.new
44
+ @current_req_id = 1
45
+ @host = host
46
+ return nil if reopen(timeout) != Zookeeper::ZOO_CONNECTED_STATE
43
47
  setup_dispatch_thread!
44
48
  end
45
-
46
- public
49
+
50
+ public
47
51
  def get(options = {})
52
+ assert_open
48
53
  assert_supported_keys(options, [:path, :watcher, :watcher_context, :callback, :callback_context])
49
54
  assert_required_keys(options, [:path])
50
55
 
@@ -56,6 +61,7 @@ public
56
61
  end
57
62
 
58
63
  def set(options = {})
64
+ assert_open
59
65
  assert_supported_keys(options, [:path, :data, :version, :callback, :callback_context])
60
66
  assert_required_keys(options, [:path])
61
67
  options[:version] ||= -1
@@ -68,6 +74,7 @@ public
68
74
  end
69
75
 
70
76
  def get_children(options = {})
77
+ assert_open
71
78
  assert_supported_keys(options, [:path, :callback, :callback_context, :watcher, :watcher_context])
72
79
  assert_required_keys(options, [:path])
73
80
 
@@ -79,6 +86,7 @@ public
79
86
  end
80
87
 
81
88
  def stat(options = {})
89
+ assert_open
82
90
  assert_supported_keys(options, [:path, :callback, :callback_context, :watcher, :watcher_context])
83
91
  assert_required_keys(options, [:path])
84
92
 
@@ -90,6 +98,7 @@ public
90
98
  end
91
99
 
92
100
  def create(options = {})
101
+ assert_open
93
102
  assert_supported_keys(options, [:path, :data, :acl, :ephemeral, :sequence, :callback, :callback_context])
94
103
  assert_required_keys(options, [:path])
95
104
 
@@ -107,6 +116,7 @@ public
107
116
  end
108
117
 
109
118
  def delete(options = {})
119
+ assert_open
110
120
  assert_supported_keys(options, [:path, :version, :callback, :callback_context])
111
121
  assert_required_keys(options, [:path])
112
122
  options[:version] ||= -1
@@ -118,6 +128,7 @@ public
118
128
  end
119
129
 
120
130
  def set_acl(options = {})
131
+ assert_open
121
132
  assert_supported_keys(options, [:path, :acl, :version, :callback, :callback_context])
122
133
  assert_required_keys(options, [:path, :acl])
123
134
  options[:version] ||= -1
@@ -129,6 +140,7 @@ public
129
140
  end
130
141
 
131
142
  def get_acl(options = {})
143
+ assert_open
132
144
  assert_supported_keys(options, [:path, :callback, :callback_context])
133
145
  assert_required_keys(options, [:path])
134
146
 
@@ -166,7 +178,7 @@ private
166
178
  if callback.respond_to?(:call)
167
179
  callback.call(hash)
168
180
  else
169
- puts "dispatch_next_callback found non-callback => #{callback.inspect}"
181
+ # puts "dispatch_next_callback found non-callback => #{callback.inspect}"
170
182
  end
171
183
  end
172
184
 
@@ -211,12 +223,23 @@ public
211
223
  end
212
224
 
213
225
  private
226
+ # TODO: Make all global puts configurable
214
227
  def get_default_global_watcher
215
228
  Proc.new { |args|
216
- puts "Ruby ZK Global CB called type=#{event_by_value(args[:type])} state=#{state_by_value(args[:state])}"
229
+ # puts "Ruby ZK Global CB called type=#{event_by_value(args[:type])} state=#{state_by_value(args[:state])}"
230
+ true
217
231
  }
218
232
  end
219
233
 
234
+ # if either of these happen, the user will need to renegotiate a connection via reopen
235
+ def assert_open
236
+ if state == ZOO_EXPIRED_SESSION_STATE
237
+ raise ZookeeperException::SessionExpired
238
+ elsif state != Zookeeper::ZOO_CONNECTED_STATE
239
+ raise ZookeeperException::ConnectionClosed
240
+ end
241
+ end
242
+
220
243
  def assert_supported_keys(args, supported)
221
244
  unless (args.keys - supported).empty?
222
245
  raise ZookeeperException::BadArguments,
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'zookeeper'
3
+ z = Zookeeper.new("localhost:2181")
4
+ path = "/testing_node"
5
+ z.get(:path => path)
6
+ z.create(:path => path, :data => "initial value", :ephemeral => true)
7
+ z.get(:path => path)
8
+ z.close()
9
+ sleep 5
10
+ begin
11
+ z.get(:path => path)
12
+ rescue Exception => e
13
+ puts "Rescued exception #{e.inspect}"
14
+ end
15
+ z.reopen
16
+ z.get(:path => path)
data/zookeeper.gemspec CHANGED
@@ -2,31 +2,29 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{zookeeper}
5
- s.version = "0.3.0"
5
+ s.version = "0.3.2"
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.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
10
- s.date = %q{2010-07-03}
9
+ s.date = %q{2010-08-17}
11
10
  s.description = %q{An interface to the Zookeeper distributed configuration server.}
12
11
  s.email = %q{}
13
12
  s.extensions = ["ext/extconf.rb"]
14
13
  s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "ext/zookeeper_c.c", "lib/zookeeper.rb"]
15
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "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_esoteric.rb", "test/test_watcher1.rb", "test/test_watcher2.rb", "zookeeper.gemspec"]
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"]
16
15
  s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/zookeeper/}
17
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Zookeeper", "--main", "README"]
18
17
  s.require_paths = ["lib", "ext"]
19
18
  s.rubyforge_project = %q{fauna}
20
- s.rubygems_version = %q{1.3.6}
21
- s.signing_key = %q{/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-private_key.pem}
19
+ s.rubygems_version = %q{1.3.7}
22
20
  s.summary = %q{An interface to the Zookeeper distributed configuration server.}
23
- s.test_files = ["test/test_basic.rb", "test/test_callback1.rb", "test/test_esoteric.rb", "test/test_watcher1.rb", "test/test_watcher2.rb"]
21
+ s.test_files = ["test/test_basic.rb", "test/test_callback1.rb", "test/test_close.rb", "test/test_esoteric.rb", "test/test_watcher1.rb", "test/test_watcher2.rb"]
24
22
 
25
23
  if s.respond_to? :specification_version then
26
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
25
  s.specification_version = 3
28
26
 
29
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
30
28
  else
31
29
  end
32
30
  else
metadata CHANGED
@@ -1,41 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zookeeper
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 23
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 3
8
- - 0
9
- version: 0.3.0
9
+ - 2
10
+ version: 0.3.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - Phillip Pearson, Eric Maland, Evan Weaver, Brian Wickman
13
14
  autorequire:
14
15
  bindir: bin
15
- cert_chain:
16
- - |
17
- -----BEGIN CERTIFICATE-----
18
- MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu
19
- MRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe
20
- Fw0wNzA5MTYxMDMzMDBaFw0wODA5MTUxMDMzMDBaMD0xDTALBgNVBAMMBGV2YW4x
21
- GDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB
22
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5C0Io89nyApnr+PvbNFge9Vs
23
- yRWAlGBUEMahpXp28VrrfXZT0rAW7JBo4PlCE3jl4nE4dzE6gAdItSycjTosrw7A
24
- Ir5+xoyl4Vb35adv56TIQQXvNz+BzlqnkAY5JN0CSBRTQb6mxS3hFyD/h4qgDosj
25
- R2RFVzHqSxCS8xq4Ny8uzOwOi+Xyu4w67fI5JvnPvMxqrlR1eaIQHmxnf76RzC46
26
- QO5QhufjAYGGXd960XzbQsQyTDUYJzrvT7AdOfiyZzKQykKt8dEpDn+QPjFTnGnT
27
- QmgJBX5WJN0lHF2l1sbv3gh4Kn1tZu+kTUqeXY6ShAoDTyvZRiFqQdwh8w2lTQID
28
- AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+WqJz3xQ
29
- XSea1hRvvHWcIMgeeC4wDQYJKoZIhvcNAQEFBQADggEBAGLZ75jfOEW8Nsl26CTt
30
- JFrWxQTcQT/UljeefVE3xYr7lc9oQjbqO3FOyued3qW7TaNEtZfSHoYeUSMYbpw1
31
- XAwocIPuSRFDGM4B+hgQGVDx8PMGiJKom4qLXjO40UZsR7QyN/u869Vj45LURm6h
32
- MBcPeqCASI+WNprj9+uZa2kmHiitrFqqfMBNlm5IFbn9XeYSta9AHVvs5QQqV2m5
33
- hIPfLqCyxsn/YgOGvo6iwyQTWyTswamaAC3HRWZxIS1sfn/Ssqa7E7oQMkv5FAXr
34
- x5rKePfXINf8XTJczkl9OBEYdE9aNdJsJpXD0asLgGVwBICS5Bjohp6mizJcDC1+
35
- yZ0=
36
- -----END CERTIFICATE-----
16
+ cert_chain: []
37
17
 
38
- date: 2010-07-03 00:00:00 -07:00
18
+ date: 2010-08-17 00:00:00 -07:00
39
19
  default_executable:
40
20
  dependencies: []
41
21
 
@@ -54,10 +34,8 @@ extra_rdoc_files:
54
34
  files:
55
35
  - CHANGELOG
56
36
  - LICENSE
57
- - Manifest
58
37
  - README
59
38
  - Rakefile
60
- - examples/cloud_config.rb
61
39
  - ext/extconf.rb
62
40
  - ext/zkc-3.3.1.tar.gz
63
41
  - ext/zookeeper_c.c
@@ -69,12 +47,14 @@ files:
69
47
  - lib/zookeeper/constants.rb
70
48
  - lib/zookeeper/exceptions.rb
71
49
  - lib/zookeeper/stat.rb
50
+ - Manifest
51
+ - zookeeper.gemspec
72
52
  - test/test_basic.rb
73
53
  - test/test_callback1.rb
54
+ - test/test_close.rb
74
55
  - test/test_esoteric.rb
75
56
  - test/test_watcher1.rb
76
57
  - test/test_watcher2.rb
77
- - zookeeper.gemspec
78
58
  has_rdoc: true
79
59
  homepage: http://blog.evanweaver.com/files/doc/fauna/zookeeper/
80
60
  licenses: []
@@ -91,16 +71,20 @@ require_paths:
91
71
  - lib
92
72
  - ext
93
73
  required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
94
75
  requirements:
95
76
  - - ">="
96
77
  - !ruby/object:Gem::Version
78
+ hash: 3
97
79
  segments:
98
80
  - 0
99
81
  version: "0"
100
82
  required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
101
84
  requirements:
102
85
  - - ">="
103
86
  - !ruby/object:Gem::Version
87
+ hash: 11
104
88
  segments:
105
89
  - 1
106
90
  - 2
@@ -108,13 +92,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
92
  requirements: []
109
93
 
110
94
  rubyforge_project: fauna
111
- rubygems_version: 1.3.6
95
+ rubygems_version: 1.3.7
112
96
  signing_key:
113
97
  specification_version: 3
114
98
  summary: An interface to the Zookeeper distributed configuration server.
115
99
  test_files:
116
100
  - test/test_basic.rb
117
101
  - test/test_callback1.rb
102
+ - test/test_close.rb
118
103
  - test/test_esoteric.rb
119
104
  - test/test_watcher1.rb
120
105
  - test/test_watcher2.rb
@@ -1,125 +0,0 @@
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.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
Binary file