zookeeper 0.3.0 → 0.3.2

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