zookeeper-ng 1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ctags_paths +1 -0
- data/.dotfiles/ruby-gemset +1 -0
- data/.dotfiles/ruby-version +1 -0
- data/.dotfiles/rvmrc +2 -0
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/.travis.yml +25 -0
- data/CHANGELOG +395 -0
- data/Gemfile +30 -0
- data/Guardfile +8 -0
- data/LICENSE +23 -0
- data/Manifest +29 -0
- data/README.markdown +85 -0
- data/Rakefile +121 -0
- data/cause-abort.rb +117 -0
- data/ext/.gitignore +6 -0
- data/ext/Rakefile +41 -0
- data/ext/c_zookeeper.rb +398 -0
- data/ext/common.h +17 -0
- data/ext/dbg.h +53 -0
- data/ext/depend +5 -0
- data/ext/event_lib.c +740 -0
- data/ext/event_lib.h +175 -0
- data/ext/extconf.rb +103 -0
- data/ext/generate_gvl_code.rb +321 -0
- data/ext/patches/zkc-3.3.5-network.patch +24 -0
- data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
- data/ext/patches/zkc-3.4.5-logging.patch +41 -0
- data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
- data/ext/patches/zkc-3.4.5-overflow.patch +11 -0
- data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
- data/ext/zkc-3.4.5.tar.gz +0 -0
- data/ext/zkrb.c +1075 -0
- data/ext/zkrb_wrapper.c +775 -0
- data/ext/zkrb_wrapper.h +350 -0
- data/ext/zkrb_wrapper_compat.c +15 -0
- data/ext/zkrb_wrapper_compat.h +11 -0
- data/ext/zookeeper_base.rb +256 -0
- data/java/java_base.rb +503 -0
- data/lib/zookeeper.rb +115 -0
- data/lib/zookeeper/acls.rb +44 -0
- data/lib/zookeeper/callbacks.rb +108 -0
- data/lib/zookeeper/client.rb +30 -0
- data/lib/zookeeper/client_methods.rb +282 -0
- data/lib/zookeeper/common.rb +122 -0
- data/lib/zookeeper/common/queue_with_pipe.rb +110 -0
- data/lib/zookeeper/compatibility.rb +138 -0
- data/lib/zookeeper/constants.rb +97 -0
- data/lib/zookeeper/continuation.rb +223 -0
- data/lib/zookeeper/core_ext.rb +58 -0
- data/lib/zookeeper/em_client.rb +55 -0
- data/lib/zookeeper/exceptions.rb +135 -0
- data/lib/zookeeper/forked.rb +19 -0
- data/lib/zookeeper/latch.rb +34 -0
- data/lib/zookeeper/logger.rb +39 -0
- data/lib/zookeeper/logger/forwarding_logger.rb +84 -0
- data/lib/zookeeper/monitor.rb +19 -0
- data/lib/zookeeper/rake_tasks.rb +165 -0
- data/lib/zookeeper/request_registry.rb +153 -0
- data/lib/zookeeper/stat.rb +21 -0
- data/lib/zookeeper/version.rb +4 -0
- data/notes.txt +14 -0
- data/scripts/upgrade-1.0-sed-alike.rb +46 -0
- data/spec/c_zookeeper_spec.rb +51 -0
- data/spec/chrooted_connection_spec.rb +83 -0
- data/spec/compatibilty_spec.rb +8 -0
- data/spec/default_watcher_spec.rb +41 -0
- data/spec/em_spec.rb +51 -0
- data/spec/ext/zookeeper_base_spec.rb +19 -0
- data/spec/forked_connection_spec.rb +124 -0
- data/spec/latch_spec.rb +24 -0
- data/spec/log4j.properties +17 -0
- data/spec/shared/all_success_return_values.rb +10 -0
- data/spec/shared/connection_examples.rb +1077 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/00_logging.rb +38 -0
- data/spec/support/10_spawn_zookeeper.rb +24 -0
- data/spec/support/progress_formatter.rb +15 -0
- data/spec/support/zookeeper_spec_helpers.rb +96 -0
- data/spec/zookeeper_spec.rb +24 -0
- data/zookeeper.gemspec +38 -0
- data/zoomonkey/duplicates +3 -0
- data/zoomonkey/zoomonkey.rb +194 -0
- metadata +157 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Forked
|
3
|
+
# the includer provides an 'original_pid' method, which is set
|
4
|
+
# when the original 'owning' process creates the object.
|
5
|
+
#
|
6
|
+
# @return [true] if the current PID differs from the original_pid value
|
7
|
+
# @return [false] if the current PID matches the original_pid value
|
8
|
+
#
|
9
|
+
def forked?
|
10
|
+
Process.pid != original_pid
|
11
|
+
end
|
12
|
+
|
13
|
+
# sets the `original_pid` to the current value
|
14
|
+
def update_pid!
|
15
|
+
self.original_pid = Process.pid
|
16
|
+
end
|
17
|
+
end # Forked
|
18
|
+
end # Zookeeper
|
19
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
# a cross-thread gate of sorts.
|
3
|
+
class Latch
|
4
|
+
def initialize(count = 1)
|
5
|
+
@count = count
|
6
|
+
@mutex = Monitor.new
|
7
|
+
@cond = @mutex.new_cond
|
8
|
+
end
|
9
|
+
|
10
|
+
def release
|
11
|
+
@mutex.synchronize {
|
12
|
+
@count -= 1 if @count > 0
|
13
|
+
@cond.broadcast if @count.zero?
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def await(timeout=nil)
|
18
|
+
@mutex.synchronize do
|
19
|
+
if timeout
|
20
|
+
time_to_stop = Time.now + timeout
|
21
|
+
|
22
|
+
while @count > 0
|
23
|
+
@cond.wait(timeout)
|
24
|
+
|
25
|
+
break if (Time.now > time_to_stop)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
@cond.wait_while { @count > 0 }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Logger
|
3
|
+
def self.wrapped_logger
|
4
|
+
if defined?(@@wrapped_logger)
|
5
|
+
@@wrapped_logger
|
6
|
+
else
|
7
|
+
@@wrapped_logger = ::Logger.new(STDERR).tap { |l| l.level = ::Logger::FATAL }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.wrapped_logger=(log)
|
12
|
+
@@wrapped_logger = log
|
13
|
+
end
|
14
|
+
|
15
|
+
# @private
|
16
|
+
module ClassMethods
|
17
|
+
def logger
|
18
|
+
::Zookeeper.logger || ForwardingLogger.for(::Zookeeper::Logger.wrapped_logger, _zk_logger_name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.included(base)
|
23
|
+
# return false if base < self # avoid infinite recursion
|
24
|
+
base.extend(ClassMethods)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def log_realtime(what)
|
29
|
+
logger.debug do
|
30
|
+
t = Benchmark.realtime { yield }
|
31
|
+
"#{what} took #{t} sec"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def logger
|
36
|
+
@logger ||= (::Zookeeper.logger || self.class.logger)
|
37
|
+
end
|
38
|
+
end # Logger
|
39
|
+
end # Zookeeper
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Logger
|
3
|
+
# h/t _eric and Papertrail
|
4
|
+
# @private
|
5
|
+
class ForwardingLogger
|
6
|
+
attr_accessor :level, :formatter
|
7
|
+
|
8
|
+
@@mutex = Monitor.new unless defined?(@@mutex)
|
9
|
+
@@loggers = {} unless defined?(@@loggers)
|
10
|
+
|
11
|
+
def self.for(logger, name)
|
12
|
+
@@mutex.synchronize do
|
13
|
+
@@loggers.fetch(name) do |k|
|
14
|
+
@@loggers[k] = new(logger, :formatter => lambda { |m| "%25.25s: %s" % [k, m] })
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(logger, options = {})
|
20
|
+
@level = ::Logger::DEBUG
|
21
|
+
@logger = logger
|
22
|
+
@formatter = options[:formatter]
|
23
|
+
end
|
24
|
+
|
25
|
+
def add(severity, message = nil, progname = nil, &block)
|
26
|
+
severity ||= ::Logger::UNKNOWN
|
27
|
+
if !@logger || severity < @level
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
message = (message || (block && block.call) || progname).to_s
|
32
|
+
|
33
|
+
if @formatter && @formatter.respond_to?(:call)
|
34
|
+
message = @formatter.call(message)
|
35
|
+
end
|
36
|
+
|
37
|
+
# If a newline is necessary then create a new message ending with a newline.
|
38
|
+
# Ensures that the original message is not mutated.
|
39
|
+
# message = "#{message}\n" unless message[-1] == ?\n
|
40
|
+
|
41
|
+
@logger.add(severity, message)
|
42
|
+
end
|
43
|
+
|
44
|
+
def <<(msg); @logger << msg; end
|
45
|
+
def write(msg); @logger.write(msg); end
|
46
|
+
|
47
|
+
def debug(progname = nil, &block)
|
48
|
+
add(::Logger::DEBUG, nil, progname, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def info(progname = nil, &block)
|
52
|
+
add(::Logger::INFO, nil, progname, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
def warn(progname = nil, &block)
|
56
|
+
add(::Logger::WARN, nil, progname, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def error(progname = nil, &block)
|
60
|
+
add(::Logger::ERROR, nil, progname, &block)
|
61
|
+
end
|
62
|
+
|
63
|
+
def fatal(progname = nil, &block)
|
64
|
+
add(::Logger::FATAL, nil, progname, &block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def unknown(progname = nil, &block)
|
68
|
+
add(::Logger::UNKNOWN, nil, progname, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def debug?; @level <= DEBUG; end
|
72
|
+
|
73
|
+
def info?; @level <= INFO; end
|
74
|
+
|
75
|
+
def warn?; @level <= WARN; end
|
76
|
+
|
77
|
+
def error?; @level <= ERROR; end
|
78
|
+
|
79
|
+
def fatal?; @level <= FATAL; end
|
80
|
+
end # ForwardingLogger
|
81
|
+
end # Logger
|
82
|
+
end # Zookeeper
|
83
|
+
|
84
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
# just like stdlib Monitor but provides the SAME API AS MUTEX, FFS!
|
3
|
+
class Monitor
|
4
|
+
include MonitorMixin
|
5
|
+
|
6
|
+
alias try_enter try_mon_enter
|
7
|
+
alias enter mon_enter
|
8
|
+
alias exit mon_exit
|
9
|
+
|
10
|
+
# here, HERE!
|
11
|
+
# *here* are the methods that are the same
|
12
|
+
# god *dammit*
|
13
|
+
|
14
|
+
alias lock mon_enter
|
15
|
+
alias unlock mon_exit
|
16
|
+
alias try_lock try_mon_enter
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module Zookeeper
|
5
|
+
# @private
|
6
|
+
module RakeTasks
|
7
|
+
def self.define_test_tasks_for(*rubies)
|
8
|
+
rubies.each do |r|
|
9
|
+
|
10
|
+
TestOneRuby.new(:name => r) do |tor|
|
11
|
+
yield tor if block_given?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestOneRuby < ::Rake::TaskLib
|
17
|
+
include ::Rake::DSL if defined?(::Rake::DSL)
|
18
|
+
|
19
|
+
DEFAULT_RVM_RUBY_NAME = '1.9.3'
|
20
|
+
|
21
|
+
# defaults to 'zk', test tasks will be built under this
|
22
|
+
attr_accessor :namespace
|
23
|
+
|
24
|
+
# the name of the task
|
25
|
+
# (tasks will be 'zk:1.9.3:run_rspec')
|
26
|
+
#
|
27
|
+
# this is mainly here so that the rvm ruby name rbx-2.0.testing
|
28
|
+
# will have its tasks defined as 'zk:rbx'
|
29
|
+
attr_accessor :name
|
30
|
+
|
31
|
+
# what is the rvm name we should use for testing? (i.e. could be an alias)
|
32
|
+
# defaults to {#name}
|
33
|
+
attr_accessor :rvm_ruby_name
|
34
|
+
|
35
|
+
# any extra environment variables?
|
36
|
+
attr_accessor :env
|
37
|
+
|
38
|
+
# gemset name to use, deafults to the name of the gemspec in the top of the
|
39
|
+
# project directory (minus the .gempsec)
|
40
|
+
attr_accessor :gemset_name
|
41
|
+
|
42
|
+
# @private
|
43
|
+
attr_reader :ruby_with_gemset,
|
44
|
+
:create_gemset_name,
|
45
|
+
:clobber_task_name,
|
46
|
+
:clean_task_name,
|
47
|
+
:build_task_name,
|
48
|
+
:bundle_task_name,
|
49
|
+
:rspec_task_name,
|
50
|
+
:phony_gemfile_link_name,
|
51
|
+
:phony_gemfile_lock_name
|
52
|
+
|
53
|
+
|
54
|
+
def self.default_gemset_name
|
55
|
+
ary = Dir['*.gemspec']
|
56
|
+
raise 'No gemspec found' if ary.empty?
|
57
|
+
ary.first[/(.+)\.gemspec\Z/, 1]
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(opts={})
|
61
|
+
@namespace = 'zk'
|
62
|
+
@name = nil
|
63
|
+
@env = {}
|
64
|
+
@rvm_ruby_name = nil
|
65
|
+
@gemset_name = nil
|
66
|
+
|
67
|
+
opts.each { |k,v| __send__(:"#{k}=", v) }
|
68
|
+
|
69
|
+
yield self if block_given?
|
70
|
+
|
71
|
+
@gemset_name ||= self.class.default_gemset_name
|
72
|
+
|
73
|
+
# XXX: add an exception just for me in here (yes, i know this is naughty)
|
74
|
+
# or else i'd have to do this in every zk variant i want to test
|
75
|
+
# (like i have to now)
|
76
|
+
|
77
|
+
unless @rvm_ruby_name
|
78
|
+
@rvm_ruby_name = 'rbx-2.0.testing' if @name == 'rbx'
|
79
|
+
end
|
80
|
+
|
81
|
+
@rvm_ruby_name ||= name
|
82
|
+
|
83
|
+
@ruby_with_gemset = "#{@rvm_ruby_name}@#{@gemset_name}"
|
84
|
+
@create_gemset_name = "#{namespace}:#{name}:create_gemset"
|
85
|
+
@clobber_task_name = "#{namespace}:#{name}:clobber"
|
86
|
+
@clean_task_name = "#{namespace}:#{name}:clean"
|
87
|
+
@build_task_name = "#{namespace}:#{name}:build"
|
88
|
+
@bundle_task_name = "#{namespace}:#{name}:bundle_install"
|
89
|
+
@rspec_task_name = "#{namespace}:#{name}:run_rspec"
|
90
|
+
@phony_gemfile_link_name = "Gemfile.#{name}"
|
91
|
+
@phony_gemfile_lock_name = "#{phony_gemfile_link_name}.lock"
|
92
|
+
|
93
|
+
define_tasks
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def need_ext_build?
|
98
|
+
name != 'jruby' && File.directory?('./ext')
|
99
|
+
end
|
100
|
+
|
101
|
+
def define_tasks
|
102
|
+
file phony_gemfile_link_name do
|
103
|
+
# apparently, rake doesn't deal with symlinks intelligently :P
|
104
|
+
ln_s('Gemfile', phony_gemfile_link_name) unless File.symlink?(phony_gemfile_link_name)
|
105
|
+
end
|
106
|
+
|
107
|
+
task :clean do
|
108
|
+
rm_rf [phony_gemfile_lock_name, phony_gemfile_lock_name]
|
109
|
+
end
|
110
|
+
|
111
|
+
task create_gemset_name do
|
112
|
+
sh "rvm #{rvm_ruby_name} do rvm gemset create #{gemset_name}"
|
113
|
+
end
|
114
|
+
|
115
|
+
task clobber_task_name do
|
116
|
+
if need_ext_build?
|
117
|
+
cd 'ext' do
|
118
|
+
sh "rake clobber"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
task clean_task_name do
|
124
|
+
if need_ext_build?
|
125
|
+
cd 'ext' do
|
126
|
+
sh "rake clean"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
task build_task_name => [create_gemset_name, clean_task_name] do
|
132
|
+
if need_ext_build?
|
133
|
+
cd 'ext' do
|
134
|
+
sh "rvm #{ruby_with_gemset} do rake build"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
task bundle_task_name => [phony_gemfile_link_name, build_task_name] do
|
140
|
+
sh "rvm #{ruby_with_gemset} do bundle install --gemfile #{phony_gemfile_link_name}"
|
141
|
+
end
|
142
|
+
|
143
|
+
task rspec_task_name => bundle_task_name do
|
144
|
+
sh "rvm #{ruby_with_gemset} do env BUNDLE_GEMFILE=#{phony_gemfile_link_name} bundle exec rspec spec --fail-fast"
|
145
|
+
end
|
146
|
+
|
147
|
+
task "#{namespace}:#{name}" => rspec_task_name
|
148
|
+
|
149
|
+
task "#{namespace}:test_all_rubies" => rspec_task_name
|
150
|
+
|
151
|
+
unless Rake::Task.task_defined?("#{namespace}:test_all")
|
152
|
+
task "#{namespace}:test_all" do
|
153
|
+
require 'benchmark'
|
154
|
+
t = Benchmark.realtime do
|
155
|
+
Rake::Task["#{namespace}:test_all_rubies"].invoke
|
156
|
+
end
|
157
|
+
|
158
|
+
$stderr.puts "Test run took: #{t} s"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
class RequestRegistry
|
3
|
+
include Constants
|
4
|
+
include Logger
|
5
|
+
|
6
|
+
# @param [Hash] opts
|
7
|
+
# @option opts [String] :chroot_path (nil) if given, will be used to
|
8
|
+
# correct a discrepancy between the C and Java clients when using a
|
9
|
+
# chrooted connection. If given, the chroot path will be stripped from
|
10
|
+
# the string returned by a `create`. It should be an absolute path.
|
11
|
+
#
|
12
|
+
def initialize(watcher, opts={})
|
13
|
+
@mutex = Monitor.new
|
14
|
+
|
15
|
+
@default_watcher = watcher
|
16
|
+
|
17
|
+
@current_req_id = 0
|
18
|
+
@watcher_reqs = {}
|
19
|
+
@completion_reqs = {}
|
20
|
+
|
21
|
+
@chroot_path = opts[:chroot_path]
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_watcher
|
25
|
+
@mutex.synchronize { @default_watcher }
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_watcher=(blk)
|
29
|
+
@mutex.synchronize { @default_watcher = blk }
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_call(meth_name, opts)
|
33
|
+
req_id = nil
|
34
|
+
@mutex.synchronize {
|
35
|
+
req_id = @current_req_id
|
36
|
+
@current_req_id += 1
|
37
|
+
setup_completion(req_id, meth_name, opts) if opts[:callback]
|
38
|
+
setup_watcher(req_id, opts) if opts[:watcher]
|
39
|
+
}
|
40
|
+
req_id
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_context_for(hash)
|
44
|
+
return nil unless hash
|
45
|
+
|
46
|
+
is_session_event = (hash[:type] == ZOO_SESSION_EVENT)
|
47
|
+
|
48
|
+
req_id = hash.fetch(:req_id)
|
49
|
+
|
50
|
+
if hash.has_key?(:rc)
|
51
|
+
get_completion(req_id, :keep => is_session_event)
|
52
|
+
else
|
53
|
+
get_watcher(req_id, :keep => is_session_event)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def clear_watchers!
|
58
|
+
@mutex.synchronize { @watcher_reqs.clear }
|
59
|
+
end
|
60
|
+
|
61
|
+
# if we're chrooted, this method will strip the chroot prefix from +path+
|
62
|
+
def strip_chroot_from(path)
|
63
|
+
return path unless (chrooted? and path and path.start_with?(@chroot_path))
|
64
|
+
path[@chroot_path.length..-1]
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def get_completion(req_id, opts={})
|
69
|
+
@mutex.synchronize do
|
70
|
+
if opts[:keep]
|
71
|
+
@completion_reqs[req_id]
|
72
|
+
else
|
73
|
+
@completion_reqs.delete(req_id)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return the watcher hash associated with the req_id. If the req_id
|
79
|
+
# is the ZKRB_GLOBAL_CB_REQ, then does not clear the req from the internal
|
80
|
+
# store, otherwise the req_id is removed.
|
81
|
+
#
|
82
|
+
def get_watcher(req_id, opts={})
|
83
|
+
@mutex.synchronize do
|
84
|
+
if Constants::ZKRB_GLOBAL_CB_REQ == req_id
|
85
|
+
{ :watcher => @default_watcher, :watcher_context => nil }
|
86
|
+
elsif opts[:keep]
|
87
|
+
@watcher_reqs[req_id]
|
88
|
+
else
|
89
|
+
@watcher_reqs.delete(req_id)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def setup_watcher(req_id, call_opts)
|
96
|
+
@mutex.synchronize do
|
97
|
+
@watcher_reqs[req_id] = {
|
98
|
+
:watcher => call_opts[:watcher],
|
99
|
+
:context => call_opts[:watcher_context]
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# as a hack, to provide consistency between the java implementation and the C
|
105
|
+
# implementation when dealing w/ chrooted connections, we override this in
|
106
|
+
# ext/zookeeper_base.rb to wrap the callback in a chroot-path-stripping block.
|
107
|
+
#
|
108
|
+
# we don't use meth_name here, but we need it in the C implementation
|
109
|
+
#
|
110
|
+
def setup_completion(req_id, meth_name, call_opts)
|
111
|
+
@mutex.synchronize do
|
112
|
+
@completion_reqs[req_id] = {
|
113
|
+
:callback => maybe_wrap_callback(meth_name, call_opts[:callback]),
|
114
|
+
:context => call_opts[:callback_context]
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# this is a hack: to provide consistency between the C and Java drivers when
|
120
|
+
# using a chrooted connection, we wrap the callback in a block that will
|
121
|
+
# strip the chroot path from the returned path (important in an async create
|
122
|
+
# sequential call). This is the only place where we can hook *just* the C
|
123
|
+
# version. The non-async manipulation is handled in ZookeeperBase#create.
|
124
|
+
#
|
125
|
+
# TODO: need to move the continuation setup into here, so that it can get
|
126
|
+
# added to the callback hash
|
127
|
+
#
|
128
|
+
def maybe_wrap_callback(meth_name, cb)
|
129
|
+
return cb unless cb and chrooted? and (meth_name == :create)
|
130
|
+
|
131
|
+
lambda do |hash|
|
132
|
+
# in this case the string will be the absolute zookeeper path (i.e.
|
133
|
+
# with the chroot still prepended to the path). Here's where we strip it off
|
134
|
+
hash[:string] = strip_chroot_from(hash[:string])
|
135
|
+
|
136
|
+
# call the original callback
|
137
|
+
cb.call(hash)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def chrooted?
|
142
|
+
@chroot_path && !@chroot_path.empty?
|
143
|
+
end
|
144
|
+
|
145
|
+
def default_watcher_proc
|
146
|
+
Proc.new { |args|
|
147
|
+
logger.debug { "Ruby ZK Global CB called type=#{event_by_value(args[:type])} state=#{state_by_value(args[:state])}" }
|
148
|
+
true
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|