zookeeper 1.2.13 → 1.2.14
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/CHANGELOG +8 -0
- data/Gemfile +12 -18
- data/README.markdown +4 -0
- data/ext/c_zookeeper.rb +7 -9
- data/ext/zkrb.c +31 -20
- data/ext/zookeeper_base.rb +1 -1
- data/java/java_base.rb +7 -0
- data/lib/zookeeper/client_methods.rb +11 -0
- data/lib/zookeeper/continuation.rb +3 -1
- data/lib/zookeeper/version.rb +1 -1
- data/spec/shared/connection_examples.rb +13 -0
- metadata +4 -4
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
v1.2.14 merge add_auth pull request, reduce chances for ContinuationTimeoutError
|
2
|
+
|
3
|
+
* added support for the add_auth call (h/t: @bradhe) see pull req #25
|
4
|
+
|
5
|
+
* fix a corner case where some pending Continuations may get stuck without
|
6
|
+
being shutdown when the event thread exits. This would lead to a
|
7
|
+
ContinuationTimeoutError being raised after 30s as a failsafe.
|
8
|
+
|
1
9
|
v1.2.13 fix build under rbenv
|
2
10
|
|
3
11
|
* h/t to Eric Lindvall for fixing #22 in http://git.io/PEPgnA
|
data/Gemfile
CHANGED
@@ -4,10 +4,6 @@ gemspec
|
|
4
4
|
|
5
5
|
gem 'rake', '~> 0.9.0'
|
6
6
|
|
7
|
-
platform :mri_19 do
|
8
|
-
gem 'simplecov', :group => :coverage, :require => false
|
9
|
-
end
|
10
|
-
|
11
7
|
group :test do
|
12
8
|
gem "rspec", "~> 2.8.0"
|
13
9
|
gem 'eventmachine', '1.0.0.beta.4'
|
@@ -16,22 +12,20 @@ group :test do
|
|
16
12
|
gem 'zk-server', '~> 1.0.0'
|
17
13
|
end
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
15
|
+
# ffs, :platform appears to be COMLETELY BROKEN so we just DO THAT HERE
|
16
|
+
# ...BY HAND
|
22
17
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
if RUBY_VERSION != '1.8.7' && !defined?(JRUBY_VERSION)
|
19
|
+
gem 'simplecov', :group => :coverage, :require => false
|
20
|
+
gem 'yard', '~> 0.8.0', :group => :docs
|
21
|
+
gem 'redcarpet', :group => :docs
|
22
|
+
|
23
|
+
group :development do
|
24
|
+
gem 'pry'
|
25
|
+
gem 'guard', :require => false
|
26
|
+
gem 'guard-rspec', :require => false
|
27
|
+
gem 'guard-shell', :require => false
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
group :development do
|
31
|
-
gem 'pry'
|
32
|
-
gem 'guard', :require => false
|
33
|
-
gem 'guard-rspec', :require => false
|
34
|
-
gem 'guard-shell', :require => false
|
35
|
-
end
|
36
|
-
|
37
31
|
# vim:ft=ruby
|
data/README.markdown
CHANGED
@@ -44,6 +44,10 @@ If you run into problems with installing this gem (specifically with linking ex.
|
|
44
44
|
|
45
45
|
[ruby-build]: https://github.com/sstephenson/ruby-build
|
46
46
|
|
47
|
+
### A note for REE users
|
48
|
+
|
49
|
+
The zookeeper client is required to send a heartbeat packet every N seconds to the server. If it misses its deadline 3 times in a row, the session will be lost. The way the client is implemented in versions `>= 1.2`, a *ruby* thread acts as the event thread (this was necessary to provide a fork-safe client with a parent process that is able to preserve state). Some users have reported issues where under load in "massive codebases," they have problems where calls will time out. Given the nature of the thread scheduler in 1.8, one should be careful if upgrading from `0.4.4` to `>= 1.2`.
|
50
|
+
|
47
51
|
## Usage
|
48
52
|
|
49
53
|
Connect to a server:
|
data/ext/c_zookeeper.rb
CHANGED
@@ -34,7 +34,7 @@ class CZookeeper
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# wrap these calls in our sync->async special sauce
|
37
|
-
%w[get set exists create delete get_acl set_acl get_children].each do |sym|
|
37
|
+
%w[get set exists create delete get_acl set_acl get_children add_auth].each do |sym|
|
38
38
|
class_eval(<<-EOS, __FILE__, __LINE__+1)
|
39
39
|
def #{sym}(*args)
|
40
40
|
submit_and_block(:#{sym}, *args)
|
@@ -278,17 +278,15 @@ class CZookeeper
|
|
278
278
|
logger.debug { "finished completions" }
|
279
279
|
end
|
280
280
|
|
281
|
-
|
282
|
-
|
283
|
-
remaining = @reg.next_batch + @reg.in_flight.values
|
281
|
+
# anything left over after all that gets the finger
|
282
|
+
remaining = @reg.next_batch + @reg.in_flight.values
|
284
283
|
|
285
|
-
|
284
|
+
logger.debug { "there are #{remaining.length} completions to awaken" }
|
286
285
|
|
287
|
-
|
286
|
+
@reg.in_flight.clear
|
288
287
|
|
289
|
-
|
290
|
-
|
291
|
-
end
|
288
|
+
while cb = remaining.shift
|
289
|
+
cb.shutdown!
|
292
290
|
end
|
293
291
|
rescue ShuttingDownException
|
294
292
|
logger.error { "event thread saw @_shutting_down, bailing without entering loop" }
|
data/ext/zkrb.c
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
* provide a fork-safe library when you have native threads you don't own
|
26
26
|
* running around. If you fork when a thread holds a mutex, and that thread
|
27
27
|
* is not the fork-caller, that mutex can never be unlocked, and is therefore
|
28
|
-
* a ticking time-bomb in the child. The only way to guarantee safety is to
|
28
|
+
* a ticking time-bomb in the child. The only way to guarantee safety is to
|
29
29
|
* either replace all of your mutexes and conditions and such after a fork
|
30
30
|
* (which is what we do on the ruby side), or avoid the problem altogether
|
31
31
|
* and not use a multithreaded library on the backend. Since we can't replace
|
@@ -42,11 +42,11 @@
|
|
42
42
|
* open socket it's got before calling zookeeper_close. This prevents
|
43
43
|
* corruption of the client/server state. Without this code, zookeeper_close
|
44
44
|
* in the child would actually send an "Ok, we're closing" message with the
|
45
|
-
* parent's session id, causing the parent to hit an assert() case in
|
45
|
+
* parent's session id, causing the parent to hit an assert() case in
|
46
46
|
* zookeeper_process, and cause a SIGABRT. With this code in place, we get back
|
47
47
|
* a ZCONNECTIONLOSS from zookeeper_close in the child (which we ignore), and
|
48
48
|
* the parent continues on.
|
49
|
-
*
|
49
|
+
*
|
50
50
|
* You will notice below we undef 'THREADED', which would be set if we were
|
51
51
|
* using the 'mt' library. We also conditionally include additional cases
|
52
52
|
* ('SYNC', 'SYNC_WATCH') inside of some of the methods defined here. These
|
@@ -138,7 +138,7 @@ inline static void assert_valid_params(VALUE reqid, VALUE path) {
|
|
138
138
|
case T_BIGNUM:
|
139
139
|
break;
|
140
140
|
default:
|
141
|
-
rb_raise(rb_eTypeError, "reqid must be Fixnum/Bignum");
|
141
|
+
rb_raise(rb_eTypeError, "reqid must be Fixnum/Bignum");
|
142
142
|
}
|
143
143
|
|
144
144
|
Check_Type(path, T_STRING);
|
@@ -212,7 +212,7 @@ static int destroy_zkrb_instance(zkrb_instance_data_t* zk) {
|
|
212
212
|
|
213
213
|
rv = zookeeper_close(zk->zh);
|
214
214
|
|
215
|
-
zkrb_debug("obj_id: %lx, zookeeper_close returned %d, calling context: %p", zk->object_id, rv, ctx);
|
215
|
+
zkrb_debug("obj_id: %lx, zookeeper_close returned %d, calling context: %p", zk->object_id, rv, ctx);
|
216
216
|
zkrb_calling_context_free((zkrb_calling_context *) ctx);
|
217
217
|
}
|
218
218
|
|
@@ -415,6 +415,19 @@ static VALUE method_sync(VALUE self, VALUE reqid, VALUE path) {
|
|
415
415
|
return INT2FIX(rc);
|
416
416
|
}
|
417
417
|
|
418
|
+
static VALUE method_add_auth(VALUE self, VALUE reqid, VALUE scheme, VALUE cert) {
|
419
|
+
int rc = ZOK;
|
420
|
+
|
421
|
+
Check_Type(scheme, T_STRING);
|
422
|
+
Check_Type(cert, T_STRING);
|
423
|
+
|
424
|
+
FETCH_DATA_PTR(self, zk);
|
425
|
+
|
426
|
+
rc = zkrb_call_zoo_add_auth(zk->zh, RSTRING_PTR(scheme), RSTRING_PTR(cert), RSTRING_LEN(cert), zkrb_void_callback, CTX_ALLOC(zk, reqid));
|
427
|
+
|
428
|
+
return INT2FIX(rc);
|
429
|
+
}
|
430
|
+
|
418
431
|
|
419
432
|
static VALUE method_create(VALUE self, VALUE reqid, VALUE path, VALUE data, VALUE async, VALUE acls, VALUE flags) {
|
420
433
|
STANDARD_PREAMBLE(self, zk, reqid, path, async, Qfalse, call_type);
|
@@ -500,7 +513,7 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
|
|
500
513
|
int data_len = MAX_ZNODE_SIZE;
|
501
514
|
struct Stat stat;
|
502
515
|
|
503
|
-
char * data = NULL;
|
516
|
+
char * data = NULL;
|
504
517
|
if (IS_SYNC(call_type)) {
|
505
518
|
data = malloc(MAX_ZNODE_SIZE); /* ugh */
|
506
519
|
memset(data, 0, sizeof(data));
|
@@ -533,7 +546,7 @@ static VALUE method_get(VALUE self, VALUE reqid, VALUE path, VALUE async, VALUE
|
|
533
546
|
|
534
547
|
default:
|
535
548
|
invalid_call_type=1;
|
536
|
-
goto cleanup;
|
549
|
+
goto cleanup;
|
537
550
|
break;
|
538
551
|
}
|
539
552
|
|
@@ -598,7 +611,7 @@ static VALUE method_set_acl(VALUE self, VALUE reqid, VALUE path, VALUE acls, VAL
|
|
598
611
|
|
599
612
|
int rc=ZOK, invalid_call_type=0;
|
600
613
|
switch (call_type) {
|
601
|
-
|
614
|
+
|
602
615
|
#ifdef THREADED
|
603
616
|
case SYNC:
|
604
617
|
rc = zkrb_call_zoo_set_acl(zk->zh, RSTRING_PTR(path), FIX2INT(version), aclptr);
|
@@ -662,7 +675,7 @@ static VALUE method_get_acl(VALUE self, VALUE reqid, VALUE path, VALUE async) {
|
|
662
675
|
#define is_shutting_down(self) RTEST(rb_iv_get(self, "@_shutting_down"))
|
663
676
|
|
664
677
|
static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
|
665
|
-
// dbg.h
|
678
|
+
// dbg.h
|
666
679
|
check_debug(!is_closed(self), "we are closed, not trying to get event");
|
667
680
|
|
668
681
|
char buf[64];
|
@@ -672,12 +685,12 @@ static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
|
|
672
685
|
check_debug(!is_closed(self), "we're closed in the middle of method_zkrb_get_next_event, bailing");
|
673
686
|
|
674
687
|
zkrb_event_t *event = zkrb_dequeue(zk->queue, 1);
|
675
|
-
|
688
|
+
|
676
689
|
if (event == NULL) {
|
677
|
-
if (NIL_P(blocking) || (blocking == Qfalse)) {
|
690
|
+
if (NIL_P(blocking) || (blocking == Qfalse)) {
|
678
691
|
goto error;
|
679
|
-
}
|
680
|
-
else {
|
692
|
+
}
|
693
|
+
else {
|
681
694
|
// if we're shutting down, don't enter this section, we don't want to block
|
682
695
|
check_debug(!is_shutting_down(self), "method_zkrb_get_next_event, we're shutting down, don't enter blocking section");
|
683
696
|
|
@@ -706,7 +719,7 @@ static VALUE method_zkrb_get_next_event(VALUE self, VALUE blocking) {
|
|
706
719
|
return hash;
|
707
720
|
}
|
708
721
|
|
709
|
-
error:
|
722
|
+
error:
|
710
723
|
return Qnil;
|
711
724
|
}
|
712
725
|
|
@@ -763,7 +776,7 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
|
|
763
776
|
FETCH_DATA_PTR(self, zk);
|
764
777
|
|
765
778
|
fd_set rfds, wfds, efds;
|
766
|
-
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
|
779
|
+
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
|
767
780
|
|
768
781
|
int fd=0, interest=0, events=0, rc=0, maxfd=0;
|
769
782
|
struct timeval tv;
|
@@ -797,7 +810,7 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
|
|
797
810
|
if (rc > 0) {
|
798
811
|
if (FD_ISSET(fd, &rfds)) {
|
799
812
|
events |= ZOOKEEPER_READ;
|
800
|
-
}
|
813
|
+
}
|
801
814
|
if (FD_ISSET(fd, &wfds)) {
|
802
815
|
events |= ZOOKEEPER_WRITE;
|
803
816
|
}
|
@@ -845,7 +858,7 @@ static VALUE method_close_handle(VALUE self) {
|
|
845
858
|
zkrb_debug_inst(self, "CLOSING_ZK_INSTANCE");
|
846
859
|
print_zkrb_instance_data(zk);
|
847
860
|
}
|
848
|
-
|
861
|
+
|
849
862
|
// this is a value on the ruby side we can check to see if destroy_zkrb_instance
|
850
863
|
// has been called
|
851
864
|
rb_iv_set(self, "@_closed", Qtrue);
|
@@ -927,6 +940,7 @@ static void zkrb_define_methods(void) {
|
|
927
940
|
rb_define_method(CZookeeper, "zkrb_set", method_set, 5);
|
928
941
|
rb_define_method(CZookeeper, "zkrb_set_acl", method_set_acl, 5);
|
929
942
|
rb_define_method(CZookeeper, "zkrb_get_acl", method_get_acl, 3);
|
943
|
+
rb_define_method(CZookeeper, "zkrb_add_auth", method_add_auth, 3);
|
930
944
|
|
931
945
|
rb_define_singleton_method(CZookeeper, "zoo_set_log_level", method_zoo_set_log_level, 1);
|
932
946
|
|
@@ -940,9 +954,6 @@ static void zkrb_define_methods(void) {
|
|
940
954
|
DEFINE_METHOD(zkrb_iterate_event_loop, 0);
|
941
955
|
DEFINE_METHOD(zkrb_get_next_event_st, 0);
|
942
956
|
|
943
|
-
// TODO
|
944
|
-
// DEFINE_METHOD(add_auth, 3);
|
945
|
-
|
946
957
|
// methods for the ruby-side event manager
|
947
958
|
DEFINE_METHOD(zkrb_get_next_event, 1);
|
948
959
|
DEFINE_METHOD(zkrb_get_next_event_st, 0);
|
data/ext/zookeeper_base.rb
CHANGED
@@ -33,7 +33,7 @@ class ZookeeperBase
|
|
33
33
|
|
34
34
|
|
35
35
|
def_delegators :czk, :get_children, :exists, :delete, :get, :set,
|
36
|
-
:set_acl, :get_acl, :client_id, :sync, :wait_until_connected
|
36
|
+
:set_acl, :get_acl, :client_id, :sync, :add_auth, :wait_until_connected
|
37
37
|
|
38
38
|
def self.threadsafe_inquisitor(*syms)
|
39
39
|
syms.each do |sym|
|
data/java/java_base.rb
CHANGED
@@ -321,6 +321,13 @@ class JavaBase
|
|
321
321
|
end
|
322
322
|
end
|
323
323
|
|
324
|
+
def add_auth(req_id, scheme, cert)
|
325
|
+
handle_keeper_exception do
|
326
|
+
jzk.addAuthInfo(scheme, cert.to_java_bytes)
|
327
|
+
Code::Ok
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
324
331
|
def create(req_id, path, data, callback, acl, flags)
|
325
332
|
handle_keeper_exception do
|
326
333
|
acl = Array(acl).map{ |a| JZKD::ACL.from_ruby_acl(a) }
|
@@ -13,6 +13,17 @@ module ClientMethods
|
|
13
13
|
super
|
14
14
|
end
|
15
15
|
|
16
|
+
def add_auth(options = {})
|
17
|
+
assert_open
|
18
|
+
assert_supported_keys(options, [:scheme, :cert])
|
19
|
+
assert_required_keys(options, [:scheme, :cert])
|
20
|
+
|
21
|
+
req_id = setup_call(:add_auth, options)
|
22
|
+
rc = super(req_id, options[:scheme], options[:cert])
|
23
|
+
|
24
|
+
{ :req_id => req_id, :rc => rc }
|
25
|
+
end
|
26
|
+
|
16
27
|
def get(options = {})
|
17
28
|
assert_open
|
18
29
|
assert_supported_keys(options, [:path, :watcher, :watcher_context, :callback, :callback_context])
|
@@ -61,8 +61,9 @@ module Zookeeper
|
|
61
61
|
:set_acl => 3,
|
62
62
|
:get_children => 2,
|
63
63
|
:state => 0,
|
64
|
+
:add_auth => 2
|
64
65
|
}
|
65
|
-
|
66
|
+
|
66
67
|
# maps the method name to the async return hash keys it should use to
|
67
68
|
# deliver the results
|
68
69
|
METH_TO_ASYNC_RESULT_KEYS = {
|
@@ -74,6 +75,7 @@ module Zookeeper
|
|
74
75
|
:get_acl => [:rc, :acl, :stat],
|
75
76
|
:set_acl => [:rc],
|
76
77
|
:get_children => [:rc, :strings, :stat],
|
78
|
+
:add_auth => [:rc]
|
77
79
|
}
|
78
80
|
|
79
81
|
attr_accessor :meth, :block, :rval
|
data/lib/zookeeper/version.rb
CHANGED
@@ -273,6 +273,19 @@ shared_examples_for "connection" do
|
|
273
273
|
end # async
|
274
274
|
end # set
|
275
275
|
|
276
|
+
describe :add_auth do
|
277
|
+
it %[should return ZOK if everything goes swimingly] do
|
278
|
+
result = zk.add_auth(:scheme => 'digest', :cert => 'test_user:test_password')
|
279
|
+
|
280
|
+
rv = result[:rc]
|
281
|
+
|
282
|
+
# gahhh, this shouldn't be like this.... :P
|
283
|
+
rv = rv.respond_to?(:intValue) ? rv.intValue : rv
|
284
|
+
|
285
|
+
rv.should == Zookeeper::ZOK
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
276
289
|
describe :get_children do
|
277
290
|
before do
|
278
291
|
@children = %w[child0 child1 child2]
|
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:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 14
|
10
|
+
version: 1.2.14
|
11
11
|
platform: ruby
|
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-08-
|
23
|
+
date: 2012-08-15 00:00:00 Z
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: logging
|