zookeeper 0.9.4 → 1.0.0.beta.1
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/.dotfiles/rvmrc +1 -0
- data/.gitignore +3 -0
- data/.gitmodules +3 -0
- data/.travis.yml +22 -0
- data/CHANGELOG +38 -5
- data/Gemfile +18 -1
- data/README.markdown +2 -0
- data/Rakefile +47 -109
- data/ext/c_zookeeper.rb +10 -6
- data/ext/zookeeper_base.rb +23 -11
- data/ext/zookeeper_c.c +14 -10
- data/java/{zookeeper_base.rb → java_base.rb} +13 -12
- data/lib/zookeeper.rb +32 -244
- data/lib/zookeeper/acls.rb +17 -13
- data/lib/zookeeper/callbacks.rb +28 -11
- data/lib/zookeeper/client.rb +30 -0
- data/lib/zookeeper/client_methods.rb +241 -0
- data/lib/zookeeper/common.rb +13 -12
- data/lib/zookeeper/common/queue_with_pipe.rb +3 -7
- data/lib/zookeeper/compatibility.rb +135 -0
- data/lib/zookeeper/constants.rb +35 -1
- data/lib/zookeeper/em_client.rb +1 -1
- data/lib/zookeeper/exceptions.rb +117 -93
- data/lib/zookeeper/rake_tasks.rb +165 -0
- data/lib/zookeeper/stat.rb +16 -16
- data/lib/zookeeper/version.rb +2 -4
- data/scripts/upgrade-1.0-sed-alike.rb +46 -0
- data/spec/c_zookeeper_spec.rb +10 -9
- data/spec/chrooted_connection_spec.rb +2 -2
- data/spec/default_watcher_spec.rb +4 -4
- data/spec/em_spec.rb +1 -1
- data/spec/shared/connection_examples.rb +52 -37
- data/spec/spec_helper.rb +22 -84
- data/spec/support/00_spawn_zookeeper.rb +20 -0
- data/spec/support/zookeeper_spec_helpers.rb +84 -0
- data/spec/zookeeper_spec.rb +1 -1
- metadata +47 -34
- data/examples/cloud_config.rb +0 -125
- data/test/test_basic.rb +0 -37
- data/test/test_callback1.rb +0 -36
- data/test/test_close.rb +0 -16
- data/test/test_esoteric.rb +0 -7
- data/test/test_watcher1.rb +0 -56
- data/test/test_watcher2.rb +0 -52
data/.dotfiles/rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.3@zookeeper --create
|
data/.gitignore
CHANGED
data/.gitmodules
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
notifications:
|
3
|
+
email:
|
4
|
+
- slyphon@gmail.com
|
5
|
+
|
6
|
+
# pull in releaseops submodule
|
7
|
+
before_install:
|
8
|
+
- git submodule update --init --recursive
|
9
|
+
|
10
|
+
env:
|
11
|
+
- SPAWN_ZOOKEEPER='true'
|
12
|
+
|
13
|
+
rvm:
|
14
|
+
- 1.9.3
|
15
|
+
- 1.9.2
|
16
|
+
- 1.8.7
|
17
|
+
- ree
|
18
|
+
- jruby-18mode
|
19
|
+
- jruby-19mode
|
20
|
+
|
21
|
+
bundler_args: --without development docs coverage
|
22
|
+
|
data/CHANGELOG
CHANGED
@@ -1,9 +1,42 @@
|
|
1
|
-
|
1
|
+
v1.0.0 Single Zookeeper namespace
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
* The top level Zookeeper class is now a module, the former Zookeeper
|
4
|
+
class is now Zookeeper::Client
|
5
|
+
|
6
|
+
* Consolidate the 6 top-level namespaces into one, Zookeeper module
|
7
|
+
|
8
|
+
ZookeeperCommon -> Zookeeper::Common
|
9
|
+
ZookeeperCallbacks -> Zookeeper::Callbacks
|
10
|
+
ZookeeperConstants -> Zookeeper::Constants
|
11
|
+
ZookeeperExceptions -> Zookeeper::Exceptions
|
12
|
+
ZookeeperACLs -> Zookeeper::ACLs
|
13
|
+
CZookeeper -> Zookeeper::CZookeeper
|
14
|
+
|
15
|
+
* Added a 'zookeeper/compatibility' file that will define the old names
|
16
|
+
and look up the new constants for users, and print a warning telling them
|
17
|
+
the change has occurred and that they should update their code
|
18
|
+
|
19
|
+
* Added scripts/upgrade-1.0-sed-alike.rb which will basically do a
|
20
|
+
find-and-replace, changing the old names to the new names (worked on
|
21
|
+
both the Zookeeper and ZK codebases).
|
22
|
+
|
23
|
+
* Java and C now use different names for the base class, to avoid the
|
24
|
+
possibility of error. Java is now JavaBase, C remains ZookeeperBase.
|
25
|
+
|
26
|
+
* All client methods are defined in the ClientMethods module and mixed
|
27
|
+
into the constructed Client class.
|
28
|
+
|
29
|
+
* Fix all requires, no longer monkey with $LOAD_PATH, use require_relative
|
30
|
+
|
31
|
+
* Bugfix for C client.
|
32
|
+
|
33
|
+
Because we release the GIL, there's the possibilty that in the middle of a
|
34
|
+
synchronous C call, ruby will have switched thread contexts and one of
|
35
|
+
those threads will call close. It seems that during normal operation, this
|
36
|
+
is not a problem, but during shutdown, this causes CPU to spike to 100% and
|
37
|
+
a deadlock. This fix essentially wraps every call to the C layer in a
|
38
|
+
mutex. There may be a slightly less heavyweight optimization in the future,
|
39
|
+
but this is the safest option at the moment.
|
7
40
|
|
8
41
|
v0.9.3 Event thread shutdown fix, Windows compatibility fix
|
9
42
|
|
data/Gemfile
CHANGED
@@ -4,11 +4,28 @@ 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
|
+
|
7
11
|
group :test do
|
8
12
|
gem "rspec", "~> 2.8.0"
|
9
|
-
gem 'flexmock', '~> 0.8.11'
|
10
13
|
gem 'eventmachine', '1.0.0.beta.4'
|
11
14
|
gem 'evented-spec', '~> 0.9.0'
|
15
|
+
|
16
|
+
gem 'zk-server', '~> 1.0.0'
|
17
|
+
end
|
18
|
+
|
19
|
+
platform :mri_19 do
|
20
|
+
gem 'simplecov', :group => :coverage, :require => false
|
21
|
+
end
|
22
|
+
|
23
|
+
group :docs do
|
24
|
+
gem 'yard', '~> 0.8.0'
|
25
|
+
|
26
|
+
platform :mri_19 do
|
27
|
+
gem 'redcarpet'
|
28
|
+
end
|
12
29
|
end
|
13
30
|
|
14
31
|
group :development do
|
data/README.markdown
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# zookeeper #
|
2
2
|
|
3
|
+
[](http://travis-ci.org/slyphon/zookeeper)
|
4
|
+
|
3
5
|
An interface to the Zookeeper cluster coordination server.
|
4
6
|
|
5
7
|
For a higher-level interface with a more convenient API and features such as locks, have a look at [ZK](https://github.com/slyphon/zk) (also available is [ZK-EventMachine](https://github.com/slyphon/zk-eventmachine) for those who prefer async).
|
data/Rakefile
CHANGED
@@ -1,114 +1,70 @@
|
|
1
|
-
|
2
|
-
# ENV.fetch('GEM_HOME').split('@').last
|
3
|
-
# end
|
4
|
-
|
5
|
-
GEM_FILES = FileList['*zookeeper-*.gem']
|
6
|
-
|
7
|
-
# need to releaase under both names until ZK is updated to use just 'zookeeper'
|
8
|
-
GEM_NAMES = %w[zookeeper slyphon-zookeeper]
|
9
|
-
|
10
|
-
namespace :mb do
|
11
|
-
namespace :gems do
|
12
|
-
task :build do
|
13
|
-
GEM_NAMES.each do |gem_name|
|
14
|
-
ENV['JAVA_GEM'] = nil
|
15
|
-
sh "rvm 1.8.7 do env ZOOKEEPER_GEM_NAME='#{gem_name}' gem build zookeeper.gemspec"
|
16
|
-
sh "rvm 1.8.7 do env JAVA_GEM=1 ZOOKEEPER_GEM_NAME='#{gem_name}' gem build zookeeper.gemspec"
|
17
|
-
end
|
18
|
-
end
|
1
|
+
release_ops_path = File.expand_path('../releaseops/lib', __FILE__)
|
19
2
|
|
20
|
-
|
21
|
-
|
3
|
+
# if the special submodule is availabe, use it
|
4
|
+
# we use a submodule because it doesn't depend on anything else (*cough* bundler)
|
5
|
+
# and can be shared across projects
|
6
|
+
#
|
7
|
+
if File.exists?(release_ops_path)
|
8
|
+
require File.join(release_ops_path, 'releaseops')
|
22
9
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
10
|
+
# sets up the multi-ruby zk:test_all rake tasks
|
11
|
+
ReleaseOps::TestTasks.define_for(*%w[1.8.7 1.9.2 jruby rbx ree 1.9.3])
|
27
12
|
|
28
|
-
|
29
|
-
|
30
|
-
|
13
|
+
# sets up the task :default => 'spec:run' and defines a simple
|
14
|
+
# "run the specs with the current rvm profile" task
|
15
|
+
ReleaseOps::TestTasks.define_simple_default_for_travis
|
31
16
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
17
|
+
# Define a task to run code coverage tests
|
18
|
+
ReleaseOps::TestTasks.define_simplecov_tasks
|
35
19
|
|
36
|
-
|
20
|
+
# set up yard:server, yard:gems, and yard:clean tasks
|
21
|
+
# for doing documentation stuff
|
22
|
+
ReleaseOps::YardTasks.define
|
37
23
|
|
38
|
-
|
24
|
+
task :clean => 'yard:clean'
|
39
25
|
|
40
|
-
|
41
|
-
|
26
|
+
namespace :zk do
|
27
|
+
namespace :gems do
|
28
|
+
task :build do
|
29
|
+
require 'tmpdir'
|
42
30
|
|
43
|
-
|
31
|
+
raise "You must specify a TAG" unless ENV['TAG']
|
44
32
|
|
45
|
-
|
46
|
-
|
47
|
-
clean_task_name = "mb:#{ns_name}:clean"
|
48
|
-
build_task_name = "mb:#{ns_name}:build"
|
49
|
-
bundle_task_name = "mb:#{ns_name}:bundle_install"
|
50
|
-
rspec_task_name = "mb:#{ns_name}:run_rspec"
|
33
|
+
ReleaseOps.with_tmpdir(:prefix => 'zookeeper') do |tmpdir|
|
34
|
+
tag = ENV['TAG']
|
51
35
|
|
52
|
-
|
53
|
-
phony_gemfile_lock_name = "#{phony_gemfile_link_name}.lock"
|
36
|
+
sh "git clone . #{tmpdir}"
|
54
37
|
|
55
|
-
|
56
|
-
# apparently, rake doesn't deal with symlinks intelligently :P
|
57
|
-
ln_s('Gemfile', phony_gemfile_link_name) unless File.symlink?(phony_gemfile_link_name)
|
58
|
-
end
|
38
|
+
orig_dir = Dir.getwd
|
59
39
|
|
60
|
-
|
61
|
-
|
62
|
-
end
|
40
|
+
cd tmpdir do
|
41
|
+
sh "git co #{tag} && git reset --hard && git clean -fdx"
|
63
42
|
|
64
|
-
|
65
|
-
|
66
|
-
|
43
|
+
ENV['JAVA_GEM'] = nil
|
44
|
+
sh "rvm 1.8.7 do gem build zookeeper.gemspec"
|
45
|
+
sh "rvm 1.8.7 do env JAVA_GEM=1 gem build zookeeper.gemspec"
|
67
46
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
sh "rvm #{ruby_with_gemset} do bundle exec rake clobber"
|
47
|
+
mv FileList['*.gem'], orig_dir
|
48
|
+
end
|
49
|
+
end
|
72
50
|
end
|
73
|
-
end
|
74
|
-
end
|
75
51
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
sh "rvm #{ruby_with_gemset} do bundle exec rake clean"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
52
|
+
task :push => :build do
|
53
|
+
gems = FileList['*.gem']
|
54
|
+
raise "No gemfiles to push!" if gems.empty?
|
83
55
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
sh "rvm #{ruby_with_gemset} do bundle exec rake build"
|
56
|
+
gems.each do |gem|
|
57
|
+
sh "gem push #{gem}"
|
58
|
+
end
|
88
59
|
end
|
89
|
-
end
|
90
|
-
end
|
91
60
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
task rspec_task_name => bundle_task_name do
|
97
|
-
sh "rvm #{ruby_with_gemset} do env BUNDLE_GEMFILE=#{phony_gemfile_link_name} bundle exec rspec spec --fail-fast"
|
98
|
-
end
|
99
|
-
|
100
|
-
task "mb:#{ns_name}" => rspec_task_name
|
101
|
-
|
102
|
-
task "mb:test_all_rubies" => rspec_task_name
|
103
|
-
end
|
61
|
+
task :clean do
|
62
|
+
rm_rf FileList['*.gem']
|
63
|
+
end
|
104
64
|
|
105
|
-
task
|
106
|
-
|
107
|
-
t = Benchmark.realtime do
|
108
|
-
Rake::Task['mb:test_all_rubies'].invoke
|
65
|
+
task :all => [:build, :push, :clean]
|
66
|
+
end
|
109
67
|
end
|
110
|
-
|
111
|
-
$stderr.puts "Test run took: #{t} s"
|
112
68
|
end
|
113
69
|
|
114
70
|
task :clobber do
|
@@ -142,23 +98,5 @@ task :build do
|
|
142
98
|
end
|
143
99
|
end
|
144
100
|
|
145
|
-
|
146
|
-
task :define do
|
147
|
-
require 'rubygems'
|
148
|
-
require 'bundler/setup'
|
149
|
-
require 'rspec/core/rake_task'
|
150
|
-
|
151
|
-
RSpec::Core::RakeTask.new('spec:runner') do |t|
|
152
|
-
t.rspec_opts = '-f d' if ENV['TRAVIS']
|
153
|
-
end
|
154
|
-
|
155
|
-
task 'spec:runner' => :build
|
156
|
-
end
|
157
|
-
|
158
|
-
task :run => :define do
|
159
|
-
Rake::Task['spec:runner'].invoke
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
task :default => 'spec:run'
|
101
|
+
task 'spec:run' => 'build:clean' unless defined?(::JRUBY_VERSION)
|
164
102
|
|
data/ext/c_zookeeper.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative '../lib/zookeeper/common'
|
2
|
+
require_relative '../lib/zookeeper/constants'
|
3
|
+
require_relative 'zookeeper_c'
|
4
|
+
|
5
|
+
# require File.expand_path('../zookeeper_c', __FILE__)
|
3
6
|
|
4
7
|
# TODO: see if we can get the destructor to handle thread/event queue teardown
|
5
8
|
# when we're garbage collected
|
9
|
+
module Zookeeper
|
6
10
|
class CZookeeper
|
7
|
-
include
|
8
|
-
include
|
9
|
-
include
|
11
|
+
include Zookeeper::Common
|
12
|
+
include Zookeeper::Constants
|
13
|
+
include Zookeeper::Exceptions
|
10
14
|
|
11
15
|
DEFAULT_SESSION_TIMEOUT_MSEC = 10000
|
12
16
|
|
@@ -209,4 +213,4 @@ class CZookeeper
|
|
209
213
|
end
|
210
214
|
end
|
211
215
|
end
|
212
|
-
|
216
|
+
end
|
data/ext/zookeeper_base.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
-
require File.expand_path('../c_zookeeper', __FILE__)
|
1
|
+
# require File.expand_path('../c_zookeeper', __FILE__)
|
2
|
+
|
3
|
+
require_relative 'c_zookeeper'
|
2
4
|
require 'forwardable'
|
3
5
|
|
4
6
|
# The low-level wrapper-specific methods for the C lib
|
5
7
|
# subclassed by the top-level Zookeeper class
|
8
|
+
module Zookeeper
|
6
9
|
class ZookeeperBase
|
7
10
|
extend Forwardable
|
8
|
-
include
|
9
|
-
include
|
10
|
-
include
|
11
|
-
include
|
12
|
-
include
|
13
|
-
include ZookeeperStat
|
11
|
+
include Zookeeper::Common # XXX: clean this up, no need to include *everything*
|
12
|
+
include Zookeeper::Callbacks
|
13
|
+
include Zookeeper::Constants
|
14
|
+
include Zookeeper::Exceptions
|
15
|
+
include Zookeeper::ACLs
|
14
16
|
|
15
17
|
# @private
|
16
18
|
class ClientShutdownException < StandardError; end
|
@@ -73,6 +75,10 @@ class ZookeeperBase
|
|
73
75
|
end
|
74
76
|
|
75
77
|
@mutex.synchronize do
|
78
|
+
# keep track of what process we were in to protect
|
79
|
+
# against reuse after fork()
|
80
|
+
@pid = Process.pid
|
81
|
+
|
76
82
|
# flushes all outstanding watcher reqs.
|
77
83
|
@watcher_reqs.clear
|
78
84
|
set_default_global_watcher
|
@@ -115,8 +121,14 @@ class ZookeeperBase
|
|
115
121
|
# if either of these happen, the user will need to renegotiate a connection via reopen
|
116
122
|
def assert_open
|
117
123
|
@mutex.synchronize do
|
118
|
-
raise
|
119
|
-
raise
|
124
|
+
raise Exceptions::SessionExpired if state == ZOO_EXPIRED_SESSION_STATE
|
125
|
+
raise Exceptions::NotConnected unless connected?
|
126
|
+
unless Process.pid == @pid
|
127
|
+
raise InheritedConnectionError, <<-EOS.gsub(/(?:^|\n)\s*/, ' ').strip
|
128
|
+
You tried to use a connection inherited from another process [#{@pid}]
|
129
|
+
You need to call reopen() after forking
|
130
|
+
EOS
|
131
|
+
end
|
120
132
|
end
|
121
133
|
end
|
122
134
|
|
@@ -195,7 +207,7 @@ protected
|
|
195
207
|
end
|
196
208
|
end
|
197
209
|
|
198
|
-
# pass this along to the
|
210
|
+
# pass this along to the Zookeeper::Common implementation
|
199
211
|
super(req_id, meth_name, call_opts)
|
200
212
|
end
|
201
213
|
|
@@ -229,4 +241,4 @@ protected
|
|
229
241
|
@chroot_path
|
230
242
|
end
|
231
243
|
end
|
232
|
-
|
244
|
+
end
|
data/ext/zookeeper_c.c
CHANGED
@@ -26,7 +26,9 @@
|
|
26
26
|
#include "zkrb_wrapper.h"
|
27
27
|
#include "dbg.h"
|
28
28
|
|
29
|
-
|
29
|
+
|
30
|
+
static VALUE mZookeeper = Qnil; // the Zookeeper module
|
31
|
+
static VALUE CZookeeper = Qnil; // the Zookeeper::CZookeeper class
|
30
32
|
static VALUE ZookeeperClientId = Qnil;
|
31
33
|
|
32
34
|
// slyphon: possibly add a lock to this for synchronizing during get_next_event
|
@@ -160,7 +162,7 @@ static VALUE method_zkrb_init(int argc, VALUE* argv, VALUE self) {
|
|
160
162
|
|
161
163
|
VALUE data;
|
162
164
|
struct zkrb_instance_data *zk_local_ctx;
|
163
|
-
data = Data_Make_Struct(
|
165
|
+
data = Data_Make_Struct(CZookeeper, struct zkrb_instance_data, 0, free_zkrb_instance_data, zk_local_ctx);
|
164
166
|
zk_local_ctx->queue = zkrb_queue_alloc();
|
165
167
|
|
166
168
|
if (zk_local_ctx->queue == NULL)
|
@@ -654,9 +656,9 @@ static VALUE method_zerror(VALUE self, VALUE errc) {
|
|
654
656
|
|
655
657
|
static void zkrb_define_methods(void) {
|
656
658
|
#define DEFINE_METHOD(method, args) { \
|
657
|
-
rb_define_method(
|
659
|
+
rb_define_method(CZookeeper, #method, method_ ## method, args); }
|
658
660
|
#define DEFINE_CLASS_METHOD(method, args) { \
|
659
|
-
rb_define_singleton_method(
|
661
|
+
rb_define_singleton_method(CZookeeper, #method, method_ ## method, args); }
|
660
662
|
|
661
663
|
// the number after the method name should be actual arity of C function - 1
|
662
664
|
DEFINE_METHOD(zkrb_init, -1);
|
@@ -686,10 +688,10 @@ static void zkrb_define_methods(void) {
|
|
686
688
|
// Make these class methods?
|
687
689
|
DEFINE_METHOD(zerror, 1);
|
688
690
|
|
689
|
-
rb_define_singleton_method(
|
691
|
+
rb_define_singleton_method(CZookeeper, "set_zkrb_debug_level", klass_method_zkrb_set_debug_level, 1);
|
690
692
|
|
691
|
-
rb_attr(
|
692
|
-
rb_define_method(
|
693
|
+
rb_attr(CZookeeper, rb_intern("selectable_io"), 1, 0, Qtrue);
|
694
|
+
rb_define_method(CZookeeper, "wake_event_loop!", method_wake_event_loop_bang, 0);
|
693
695
|
|
694
696
|
}
|
695
697
|
|
@@ -712,11 +714,13 @@ static VALUE zkrb_client_id_method_initialize(VALUE self) {
|
|
712
714
|
void Init_zookeeper_c() {
|
713
715
|
ZKRBDebugging = 0;
|
714
716
|
|
715
|
-
|
716
|
-
|
717
|
+
mZookeeper = rb_define_module("Zookeeper");
|
718
|
+
|
719
|
+
/* initialize CZookeeper class */
|
720
|
+
CZookeeper = rb_define_class_under(mZookeeper, "CZookeeper", rb_cObject);
|
717
721
|
zkrb_define_methods();
|
718
722
|
|
719
|
-
ZookeeperClientId = rb_define_class_under(
|
723
|
+
ZookeeperClientId = rb_define_class_under(CZookeeper, "ClientId", rb_cObject);
|
720
724
|
rb_define_method(ZookeeperClientId, "initialize", zkrb_client_id_method_initialize, 0);
|
721
725
|
rb_define_attr(ZookeeperClientId, "session_id", 1, 1);
|
722
726
|
rb_define_attr(ZookeeperClientId, "passwd", 1, 1);
|