zookeeper-ng 1.5.2.1-java
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.
- 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/.github/workflows/build.yml +57 -0
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/CHANGELOG +408 -0
- data/Gemfile +30 -0
- data/Guardfile +8 -0
- data/LICENSE +23 -0
- data/Manifest +29 -0
- data/README.markdown +62 -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-buffer-overflow.patch +11 -0
- data/ext/patches/zkc-3.4.5-config.patch +5454 -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-yosemite-htonl-fix.patch +102 -0
- data/ext/zkc-3.4.5.tar.gz +0 -0
- data/ext/zkrb.c +1080 -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 +501 -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/queue_with_pipe.rb +110 -0
- data/lib/zookeeper/common.rb +122 -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/forwarding_logger.rb +84 -0
- data/lib/zookeeper/logger.rb +39 -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/lib/zookeeper.rb +115 -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 +122 -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 +1081 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/00_logging.rb +38 -0
- data/spec/support/10_spawn_zookeeper.rb +20 -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 +46 -0
- data/zoomonkey/duplicates +3 -0
- data/zoomonkey/zoomonkey.rb +194 -0
- metadata +185 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Constants
|
3
|
+
include ACLs::Constants
|
4
|
+
|
5
|
+
# file type masks
|
6
|
+
ZOO_EPHEMERAL = 1
|
7
|
+
ZOO_SEQUENCE = 2
|
8
|
+
|
9
|
+
# session state
|
10
|
+
ZOO_EXPIRED_SESSION_STATE = -112
|
11
|
+
ZOO_AUTH_FAILED_STATE = -113
|
12
|
+
ZOO_CLOSED_STATE = 0
|
13
|
+
ZOO_CONNECTING_STATE = 1
|
14
|
+
ZOO_ASSOCIATING_STATE = 2
|
15
|
+
ZOO_CONNECTED_STATE = 3
|
16
|
+
|
17
|
+
# watch types
|
18
|
+
ZOO_CREATED_EVENT = 1
|
19
|
+
ZOO_DELETED_EVENT = 2
|
20
|
+
ZOO_CHANGED_EVENT = 3
|
21
|
+
ZOO_CHILD_EVENT = 4
|
22
|
+
ZOO_SESSION_EVENT = -1
|
23
|
+
ZOO_NOTWATCHING_EVENT = -2
|
24
|
+
|
25
|
+
# only used by the C extension
|
26
|
+
ZOO_LOG_LEVEL_ERROR = 1
|
27
|
+
ZOO_LOG_LEVEL_WARN = 2
|
28
|
+
ZOO_LOG_LEVEL_INFO = 3
|
29
|
+
ZOO_LOG_LEVEL_DEBUG = 4
|
30
|
+
|
31
|
+
# exceptions/errors
|
32
|
+
ZOK = 0
|
33
|
+
ZSYSTEMERROR = -1
|
34
|
+
ZRUNTIMEINCONSISTENCY = -2
|
35
|
+
ZDATAINCONSISTENCY = -3
|
36
|
+
ZCONNECTIONLOSS = -4
|
37
|
+
ZMARSHALLINGERROR = -5
|
38
|
+
ZUNIMPLEMENTED = -6
|
39
|
+
ZOPERATIONTIMEOUT = -7
|
40
|
+
ZBADARGUMENTS = -8
|
41
|
+
ZINVALIDSTATE = -9
|
42
|
+
|
43
|
+
# api errors
|
44
|
+
ZAPIERROR = -100
|
45
|
+
ZNONODE = -101
|
46
|
+
ZNOAUTH = -102
|
47
|
+
ZBADVERSION = -103
|
48
|
+
ZNOCHILDRENFOREPHEMERALS = -108
|
49
|
+
ZNODEEXISTS = -110
|
50
|
+
ZNOTEMPTY = -111
|
51
|
+
ZSESSIONEXPIRED = -112
|
52
|
+
ZINVALIDCALLBACK = -113
|
53
|
+
ZINVALIDACL = -114
|
54
|
+
ZAUTHFAILED = -115
|
55
|
+
ZCLOSING = -116
|
56
|
+
ZNOTHING = -117
|
57
|
+
ZSESSIONMOVED = -118
|
58
|
+
|
59
|
+
ZKRB_GLOBAL_CB_REQ = -1
|
60
|
+
ZKRB_ASYNC_CONTN_ID = -2
|
61
|
+
|
62
|
+
# @private
|
63
|
+
CONNECTED_EVENT_VALUES = [Constants::ZKRB_GLOBAL_CB_REQ,
|
64
|
+
Constants::ZOO_SESSION_EVENT,
|
65
|
+
Constants::ZOO_CONNECTED_STATE].freeze
|
66
|
+
|
67
|
+
# used to find the name for a numeric event
|
68
|
+
# @private
|
69
|
+
EVENT_TYPE_NAMES = {
|
70
|
+
1 => 'created',
|
71
|
+
2 => 'deleted',
|
72
|
+
3 => 'changed',
|
73
|
+
4 => 'child',
|
74
|
+
-1 => 'session',
|
75
|
+
-2 => 'notwatching',
|
76
|
+
}
|
77
|
+
|
78
|
+
# used to pretty print the state name
|
79
|
+
# @private
|
80
|
+
STATE_NAMES = {
|
81
|
+
-112 => 'expired_session',
|
82
|
+
-113 => 'auth_failed',
|
83
|
+
0 => 'closed',
|
84
|
+
1 => 'connecting',
|
85
|
+
2 => 'associating',
|
86
|
+
3 => 'connected',
|
87
|
+
}
|
88
|
+
|
89
|
+
def event_by_value(v)
|
90
|
+
(name = EVENT_TYPE_NAMES[v]) ? "ZOO_#{name.upcase}_EVENT" : ''
|
91
|
+
end
|
92
|
+
|
93
|
+
def state_by_value(v)
|
94
|
+
(name = STATE_NAMES[v]) ? "ZOO_#{name.upcase}_STATE" : ''
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
# @private
|
3
|
+
# sigh, slightly different than the userland callbacks, the continuation
|
4
|
+
# provides sync call semantics around an async api
|
5
|
+
class Continuation
|
6
|
+
include Constants
|
7
|
+
include Logger
|
8
|
+
|
9
|
+
OPERATION_TIMEOUT = 30 # seconds
|
10
|
+
|
11
|
+
# for keeping track of which continuations are pending, and which ones have
|
12
|
+
# been submitted and are awaiting a repsonse
|
13
|
+
#
|
14
|
+
# `state_check` are high-priority checks that query the connection about
|
15
|
+
# its current state, they always run before other continuations
|
16
|
+
#
|
17
|
+
class Registry < Struct.new(:pending, :state_check, :in_flight)
|
18
|
+
extend Forwardable
|
19
|
+
|
20
|
+
def_delegators :@mutex, :lock, :unlock
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
super([], [], {})
|
24
|
+
@mutex = Mutex.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def synchronize
|
28
|
+
@mutex.lock
|
29
|
+
begin
|
30
|
+
yield self
|
31
|
+
ensure
|
32
|
+
@mutex.unlock rescue nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# does not lock the mutex, returns true if there are pending jobs
|
37
|
+
def anything_to_do?
|
38
|
+
(pending.length + state_check.length) > 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# returns the pending continuations, resetting the list
|
42
|
+
# this method is synchronized
|
43
|
+
def next_batch()
|
44
|
+
@mutex.lock
|
45
|
+
begin
|
46
|
+
state_check.slice!(0, state_check.length) + pending.slice!(0,pending.length)
|
47
|
+
ensure
|
48
|
+
@mutex.unlock rescue nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end # Registry
|
52
|
+
|
53
|
+
# *sigh* what is the index in the *args array of the 'callback' param
|
54
|
+
CALLBACK_ARG_IDX = {
|
55
|
+
:get => 2,
|
56
|
+
:set => 3,
|
57
|
+
:exists => 2,
|
58
|
+
:create => 3,
|
59
|
+
:delete => 3,
|
60
|
+
:get_acl => 2,
|
61
|
+
:set_acl => 3,
|
62
|
+
:get_children => 2,
|
63
|
+
:state => 0,
|
64
|
+
:add_auth => 2
|
65
|
+
}
|
66
|
+
|
67
|
+
# maps the method name to the async return hash keys it should use to
|
68
|
+
# deliver the results
|
69
|
+
METH_TO_ASYNC_RESULT_KEYS = {
|
70
|
+
:get => [:rc, :data, :stat],
|
71
|
+
:set => [:rc, :stat],
|
72
|
+
:exists => [:rc, :stat],
|
73
|
+
:create => [:rc, :string],
|
74
|
+
:delete => [:rc],
|
75
|
+
:get_acl => [:rc, :acl, :stat],
|
76
|
+
:set_acl => [:rc],
|
77
|
+
:get_children => [:rc, :strings, :stat],
|
78
|
+
:add_auth => [:rc]
|
79
|
+
}
|
80
|
+
|
81
|
+
attr_accessor :meth, :block, :rval
|
82
|
+
|
83
|
+
attr_reader :args
|
84
|
+
|
85
|
+
def initialize(meth, *args)
|
86
|
+
@meth = meth
|
87
|
+
@args = args.freeze
|
88
|
+
@mutex = Monitor.new
|
89
|
+
@cond = @mutex.new_cond
|
90
|
+
@rval = nil
|
91
|
+
|
92
|
+
# make this error reporting more robust if necessary, right now, just set to state
|
93
|
+
@error = nil
|
94
|
+
end
|
95
|
+
|
96
|
+
# the caller calls this method and receives the response from the async loop
|
97
|
+
# this method has a hard-coded 30 second timeout as a safety feature. No
|
98
|
+
# call should take more than 20s (as the session timeout is set to 20s)
|
99
|
+
# so if any call takes longer than that, something has gone horribly wrong.
|
100
|
+
#
|
101
|
+
# @raise [ContinuationTimeoutError] if a response is not received within 30s
|
102
|
+
#
|
103
|
+
def value
|
104
|
+
time_to_stop = Time.now + OPERATION_TIMEOUT
|
105
|
+
now = nil
|
106
|
+
|
107
|
+
@mutex.synchronize do
|
108
|
+
while true
|
109
|
+
now = Time.now
|
110
|
+
break if @rval or @error or (now > time_to_stop)
|
111
|
+
|
112
|
+
deadline = time_to_stop.to_f - now.to_f
|
113
|
+
@cond.wait(deadline)
|
114
|
+
end
|
115
|
+
|
116
|
+
if (now > time_to_stop) and !@rval and !@error
|
117
|
+
raise Exceptions::ContinuationTimeoutError, "response for meth: #{meth.inspect}, args: #{@args.inspect}, not received within #{OPERATION_TIMEOUT} seconds"
|
118
|
+
end
|
119
|
+
|
120
|
+
case @error
|
121
|
+
when nil
|
122
|
+
# ok, nothing to see here, carry on
|
123
|
+
when :shutdown
|
124
|
+
raise Exceptions::NotConnected, "the connection is shutting down"
|
125
|
+
when ZOO_EXPIRED_SESSION_STATE
|
126
|
+
raise Exceptions::SessionExpired, "connection has expired"
|
127
|
+
else
|
128
|
+
raise Exceptions::NotConnected, "connection state is #{STATE_NAMES[@error]}"
|
129
|
+
end
|
130
|
+
|
131
|
+
case @rval.length
|
132
|
+
when 1
|
133
|
+
return @rval.first
|
134
|
+
else
|
135
|
+
return @rval
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# receive the response from the server, set @rval, notify caller
|
141
|
+
def call(hash)
|
142
|
+
logger.debug { "continuation req_id #{req_id}, got hash: #{hash.inspect}" }
|
143
|
+
@rval = hash.values_at(*METH_TO_ASYNC_RESULT_KEYS.fetch(meth))
|
144
|
+
logger.debug { "delivering result #{@rval.inspect}" }
|
145
|
+
deliver!
|
146
|
+
end
|
147
|
+
|
148
|
+
def user_callback?
|
149
|
+
!!@args.at(callback_arg_idx)
|
150
|
+
end
|
151
|
+
|
152
|
+
# this method is called by the event thread to submit the request
|
153
|
+
# passed the CZookeeper instance, makes the async call and deals with the results
|
154
|
+
#
|
155
|
+
# BTW: in case you were wondering this is a completely stupid
|
156
|
+
# implementation, but it's more important to get *something* working and
|
157
|
+
# passing specs, then refactor to make everything sane
|
158
|
+
#
|
159
|
+
#
|
160
|
+
def submit(czk)
|
161
|
+
state = czk.zkrb_state # check the state of the connection
|
162
|
+
|
163
|
+
if @meth == :state # if the method is a state call
|
164
|
+
@rval = [state] # we're done, no error
|
165
|
+
return deliver!
|
166
|
+
|
167
|
+
elsif state != ZOO_CONNECTED_STATE # otherwise, we must be connected
|
168
|
+
@error = state # so set the error
|
169
|
+
return deliver! # and we're out
|
170
|
+
end
|
171
|
+
|
172
|
+
rc, *_ = czk.__send__(:"zkrb_#{@meth}", *async_args)
|
173
|
+
|
174
|
+
if user_callback? or (rc != ZOK) # async call, or we failed to submit it
|
175
|
+
@rval = [rc] # create the repsonse
|
176
|
+
deliver! # wake the caller and we're out
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def req_id
|
181
|
+
@args.first
|
182
|
+
end
|
183
|
+
|
184
|
+
def state_call?
|
185
|
+
@meth == :state
|
186
|
+
end
|
187
|
+
|
188
|
+
# interrupt the sleeping thread with a NotConnected error
|
189
|
+
def shutdown!
|
190
|
+
@mutex.synchronize do
|
191
|
+
return if @rval or @error
|
192
|
+
@error = :shutdown
|
193
|
+
@cond.broadcast
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
protected
|
198
|
+
|
199
|
+
# an args array with the only difference being that if there's a user
|
200
|
+
# callback provided, we don't handle delivering the end result
|
201
|
+
def async_args
|
202
|
+
return [] if @meth == :state # special-case :P
|
203
|
+
ary = @args.dup
|
204
|
+
|
205
|
+
logger.debug { "async_args, meth: #{meth} ary: #{ary.inspect}, #{callback_arg_idx}" }
|
206
|
+
|
207
|
+
ary[callback_arg_idx] ||= self
|
208
|
+
|
209
|
+
ary
|
210
|
+
end
|
211
|
+
|
212
|
+
def callback_arg_idx
|
213
|
+
CALLBACK_ARG_IDX.fetch(meth) { raise ArgumentError, "unknown method #{meth.inspect}" }
|
214
|
+
end
|
215
|
+
|
216
|
+
def deliver!
|
217
|
+
@mutex.synchronize do
|
218
|
+
@cond.signal
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end # Base
|
222
|
+
end
|
223
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# @private
|
2
|
+
module ::Kernel
|
3
|
+
unless method_defined?(:silence_warnings)
|
4
|
+
def silence_warnings
|
5
|
+
with_warnings(nil) { yield }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
unless method_defined?(:with_warnings)
|
10
|
+
def with_warnings(flag)
|
11
|
+
old_verbose, $VERBOSE = $VERBOSE, flag
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
$VERBOSE = old_verbose
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @private
|
20
|
+
class ::Exception
|
21
|
+
unless method_defined?(:to_std_format)
|
22
|
+
def to_std_format
|
23
|
+
ary = ["#{self.class}: #{message}"]
|
24
|
+
ary.concat(backtrace || [])
|
25
|
+
ary.join("\n\t")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# this is borrowed from the excellent Logging gem: https://github.com/TwP/logging
|
31
|
+
# @private
|
32
|
+
class ::Module
|
33
|
+
# @private
|
34
|
+
# Returns a predictable logger name for the current module or class. If
|
35
|
+
# used within an anonymous class, the first non-anonymous class name will
|
36
|
+
# be used as the logger name. If used within a meta-class, the name of the
|
37
|
+
# actual class will be used as the logger name. If used within an
|
38
|
+
# anonymous module, the string 'anonymous' will be returned.
|
39
|
+
def _zk_logger_name
|
40
|
+
return name unless name.nil? or name.empty?
|
41
|
+
|
42
|
+
# check if this is a metaclass (or eigenclass)
|
43
|
+
if ancestors.include? Class
|
44
|
+
inspect =~ %r/#<Class:([^#>]+)>/
|
45
|
+
return $1
|
46
|
+
end
|
47
|
+
|
48
|
+
# see if we have a superclass
|
49
|
+
if respond_to? :superclass
|
50
|
+
return superclass.logger_name
|
51
|
+
end
|
52
|
+
|
53
|
+
# we are an anonymous module
|
54
|
+
return 'anonymous'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'zookeeper'
|
2
|
+
require 'eventmachine'
|
3
|
+
|
4
|
+
module ZookeeperEM
|
5
|
+
class Client < Zookeeper::Client
|
6
|
+
# @private
|
7
|
+
# the EM Connection instance we receive once we call EM.watch on our selectable_io
|
8
|
+
attr_reader :em_connection
|
9
|
+
|
10
|
+
def initialize(*a, &b)
|
11
|
+
@on_close = EM::DefaultDeferrable.new
|
12
|
+
@on_attached = EM::DefaultDeferrable.new
|
13
|
+
@em_connection = nil
|
14
|
+
logger.debug { "ZookeeperEM::Client obj_id %x: init" % [object_id] }
|
15
|
+
super(*a, &b)
|
16
|
+
on_attached.succeed
|
17
|
+
end
|
18
|
+
|
19
|
+
# EM::DefaultDeferrable that will be called back when our em_connection has been detached
|
20
|
+
# and we've completed the close operation
|
21
|
+
def on_close(&block)
|
22
|
+
@on_close.callback(&block) if block
|
23
|
+
@on_close
|
24
|
+
end
|
25
|
+
|
26
|
+
# called after we've successfully registered our selectable_io to be
|
27
|
+
# managed by the EM reactor
|
28
|
+
def on_attached(&block)
|
29
|
+
@on_attached.callback(&block) if block
|
30
|
+
@on_attached
|
31
|
+
end
|
32
|
+
|
33
|
+
def dispatch_next_callback(hash)
|
34
|
+
EM.schedule do
|
35
|
+
if running? and not closed?
|
36
|
+
logger.debug { "#{self.class}##{__method__} dispatch_next_callback: #{hash.inspect}: reactor_thread? #{EM.reactor_thread?}, running? #{running?}, closed? #{closed?}" }
|
37
|
+
super(hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def close(&block)
|
43
|
+
on_close(&block)
|
44
|
+
super()
|
45
|
+
on_close.succeed
|
46
|
+
end
|
47
|
+
|
48
|
+
# Because eventmachine is single-threaded, and events are dispatched on the
|
49
|
+
# reactor thread we just delegate this to EM.reactor_thread?
|
50
|
+
def event_dispatch_thread?
|
51
|
+
EM.reactor_thread?
|
52
|
+
end
|
53
|
+
end # Client
|
54
|
+
end # ZookeeperEM
|
55
|
+
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Zookeeper
|
2
|
+
module Exceptions
|
3
|
+
include Constants
|
4
|
+
|
5
|
+
class ZookeeperException < StandardError
|
6
|
+
|
7
|
+
unless defined?(CONST_MISSING_WARNING)
|
8
|
+
|
9
|
+
CONST_MISSING_WARNING = <<-EOS
|
10
|
+
|
11
|
+
------------------------------------------------------------------------------------------
|
12
|
+
WARNING! THE ZOOKEEPER NAMESPACE HAS CHANGED AS OF 1.0!
|
13
|
+
|
14
|
+
Please update your code to use the new hierarchy!
|
15
|
+
|
16
|
+
The constant that got you this was ZookeeperExceptions::ZookeeperException::%s
|
17
|
+
|
18
|
+
stacktrace:
|
19
|
+
%s
|
20
|
+
|
21
|
+
------------------------------------------------------------------------------------------
|
22
|
+
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
# NOTE(slyphon): Since 0.4 all of the ZookeeperException subclasses were
|
27
|
+
# defined inside of ZookeeperException, which always seemed well, icky.
|
28
|
+
# if someone references one of these we'll print out a warning and
|
29
|
+
# then give them the constant
|
30
|
+
#
|
31
|
+
def self.const_missing(const)
|
32
|
+
if Zookeeper::Exceptions.const_defined?(const)
|
33
|
+
|
34
|
+
stacktrace = caller[0..-2].reject {|n| n =~ %r%/rspec/% }.map { |n| "\t#{n}" }.join("\n")
|
35
|
+
|
36
|
+
Zookeeper.deprecation_warning(CONST_MISSING_WARNING % [const.to_s, stacktrace])
|
37
|
+
|
38
|
+
|
39
|
+
Zookeeper::Exceptions.const_get(const).tap do |const_val|
|
40
|
+
self.const_set(const, const_val)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
class EverythingOk < ZookeeperException; end
|
50
|
+
class SystemError < ZookeeperException; end
|
51
|
+
class RunTimeInconsistency < ZookeeperException; end
|
52
|
+
class DataInconsistency < ZookeeperException; end
|
53
|
+
class ConnectionLoss < ZookeeperException; end
|
54
|
+
class MarshallingError < ZookeeperException; end
|
55
|
+
class Unimplemented < ZookeeperException; end
|
56
|
+
class OperationTimeOut < ZookeeperException; end
|
57
|
+
class BadArguments < ZookeeperException; end
|
58
|
+
class InvalidState < ZookeeperException; end
|
59
|
+
class ApiError < ZookeeperException; end
|
60
|
+
class NoNode < ZookeeperException; end
|
61
|
+
class NoAuth < ZookeeperException; end
|
62
|
+
class BadVersion < ZookeeperException; end
|
63
|
+
class NoChildrenForEphemerals < ZookeeperException; end
|
64
|
+
class NodeExists < ZookeeperException; end
|
65
|
+
class NotEmpty < ZookeeperException; end
|
66
|
+
class SessionExpired < ZookeeperException; end
|
67
|
+
class InvalidCallback < ZookeeperException; end
|
68
|
+
class InvalidACL < ZookeeperException; end
|
69
|
+
class AuthFailed < ZookeeperException; end
|
70
|
+
class Closing < ZookeeperException; end
|
71
|
+
class Nothing < ZookeeperException; end
|
72
|
+
class SessionMoved < ZookeeperException; end
|
73
|
+
|
74
|
+
# these are Ruby client exceptions
|
75
|
+
class ConnectionClosed < ZookeeperException; end
|
76
|
+
class NotConnected < ZookeeperException; end
|
77
|
+
class ShuttingDownException < ZookeeperException; end
|
78
|
+
class DataTooLargeException < ZookeeperException; end
|
79
|
+
|
80
|
+
# raised when an operation is performed on an instance without a valid
|
81
|
+
# zookeeper handle. (C version)
|
82
|
+
class HandleClosedException < ZookeeperException; end
|
83
|
+
|
84
|
+
# maybe use this for continuation
|
85
|
+
class InterruptedException < ZookeeperException ; end
|
86
|
+
|
87
|
+
# raised when a continuation operation takes more time than is reasonable and
|
88
|
+
# the thread should be awoken. (i.e. prevents a call that never returns)
|
89
|
+
class ContinuationTimeoutError < ZookeeperException; end
|
90
|
+
|
91
|
+
# raised when the user tries to use a connection after a fork()
|
92
|
+
# without calling reopen() in the C client
|
93
|
+
#
|
94
|
+
# (h/t: @pletern http://git.io/zIsq1Q)
|
95
|
+
class InheritedConnectionError < ZookeeperException; end
|
96
|
+
|
97
|
+
# yes, make an alias, this is the way zookeeper refers to it
|
98
|
+
ExpiredSession = SessionExpired unless defined?(ExpiredSession)
|
99
|
+
|
100
|
+
def self.by_code(code)
|
101
|
+
case code
|
102
|
+
when ZOK then EverythingOk
|
103
|
+
when ZSYSTEMERROR then SystemError
|
104
|
+
when ZRUNTIMEINCONSISTENCY then RunTimeInconsistency
|
105
|
+
when ZDATAINCONSISTENCY then DataInconsistency
|
106
|
+
when ZCONNECTIONLOSS then ConnectionLoss
|
107
|
+
when ZMARSHALLINGERROR then MarshallingError
|
108
|
+
when ZUNIMPLEMENTED then Unimplemented
|
109
|
+
when ZOPERATIONTIMEOUT then OperationTimeOut
|
110
|
+
when ZBADARGUMENTS then BadArguments
|
111
|
+
when ZINVALIDSTATE then InvalidState
|
112
|
+
when ZAPIERROR then ApiError
|
113
|
+
when ZNONODE then NoNode
|
114
|
+
when ZNOAUTH then NoAuth
|
115
|
+
when ZBADVERSION then BadVersion
|
116
|
+
when ZNOCHILDRENFOREPHEMERALS then NoChildrenForEphemerals
|
117
|
+
when ZNODEEXISTS then NodeExists
|
118
|
+
when ZNOTEMPTY then NotEmpty
|
119
|
+
when ZSESSIONEXPIRED then SessionExpired
|
120
|
+
when ZINVALIDCALLBACK then InvalidCallback
|
121
|
+
when ZINVALIDACL then InvalidACL
|
122
|
+
when ZAUTHFAILED then AuthFailed
|
123
|
+
when ZCLOSING then Closing
|
124
|
+
when ZNOTHING then Nothing
|
125
|
+
when ZSESSIONMOVED then SessionMoved
|
126
|
+
else ZookeeperException.new("no exception defined for code #{code}")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.raise_on_error(code)
|
131
|
+
exc = self.by_code(code)
|
132
|
+
raise exc unless exc == EverythingOk
|
133
|
+
end
|
134
|
+
end # Exceptions
|
135
|
+
end # Zookeeper
|
@@ -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,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
|
+
|