zookeeper 1.2.2 → 1.2.3
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/CHANGELOG +9 -0
- data/ext/c_zookeeper.rb +28 -11
- data/lib/zookeeper.rb +1 -1
- data/lib/zookeeper/common.rb +1 -1
- data/lib/zookeeper/continuation.rb +12 -5
- data/lib/zookeeper/version.rb +1 -1
- data/spec/chrooted_connection_spec.rb +1 -1
- data/spec/shared/connection_examples.rb +1 -1
- data/spec/support/00_logging.rb +3 -1
- metadata +5 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
v1.2.3 ensure that all threads are woken up on shutdown
|
2
|
+
|
3
|
+
* There was an edge case where a call would be queued up and its thread
|
4
|
+
sleeping waiting for a response, but that response would never come because
|
5
|
+
the connection was shut down. This version includes a patch for that case
|
6
|
+
to ensure that if a call is in 'pending' state, and shutdown time arrives
|
7
|
+
that all pending threads will receive a Zookeeper::Exceptions::NotConnected
|
8
|
+
exception.
|
9
|
+
|
1
10
|
v1.2.2 avoid race while waiting for connection
|
2
11
|
|
3
12
|
* There was a possible race in CZookeeper#wait_until_connected where if we
|
data/ext/c_zookeeper.rb
CHANGED
@@ -143,13 +143,13 @@ class CZookeeper
|
|
143
143
|
# requests may still be added during this time, but they will not be
|
144
144
|
# processed until you call resume
|
145
145
|
def pause_before_fork_in_parent
|
146
|
-
logger.debug { "
|
146
|
+
logger.debug { "##{__method__}" }
|
147
147
|
@mutex.synchronize { stop_event_thread }
|
148
148
|
end
|
149
149
|
|
150
150
|
# call this if 'pause' was previously called to start the event loop again
|
151
151
|
def resume_after_fork_in_parent
|
152
|
-
logger.debug { "
|
152
|
+
logger.debug { "##{__method__}" }
|
153
153
|
|
154
154
|
@mutex.synchronize do
|
155
155
|
@_shutting_down = nil
|
@@ -184,6 +184,10 @@ class CZookeeper
|
|
184
184
|
# submits a job for processing
|
185
185
|
# blocks the caller until result has returned
|
186
186
|
def submit_and_block(meth, *args)
|
187
|
+
@mutex.synchronize do
|
188
|
+
raise Exceptions::NotConnected if @_shutting_down
|
189
|
+
end
|
190
|
+
|
187
191
|
cnt = Continuation.new(meth, *args)
|
188
192
|
@reg.lock
|
189
193
|
begin
|
@@ -206,7 +210,7 @@ class CZookeeper
|
|
206
210
|
#
|
207
211
|
def stop_event_thread
|
208
212
|
if @event_thread
|
209
|
-
logger.debug { "
|
213
|
+
logger.debug { "##{__method__}" }
|
210
214
|
shut_down!
|
211
215
|
wake_event_loop!
|
212
216
|
@event_thread.join
|
@@ -235,7 +239,7 @@ class CZookeeper
|
|
235
239
|
|
236
240
|
def event_thread_body
|
237
241
|
Thread.current.abort_on_exception = true
|
238
|
-
logger.debug { "
|
242
|
+
logger.debug { "##{__method__} starting event thread" }
|
239
243
|
|
240
244
|
event_thread_await_running
|
241
245
|
|
@@ -249,21 +253,34 @@ class CZookeeper
|
|
249
253
|
# ok, if we're exiting the event loop, and we still have a valid connection
|
250
254
|
# and there's still completions we're waiting to hear about, then we
|
251
255
|
# should pump the handle before leaving this loop
|
252
|
-
if @_shutting_down and not (@_closed or is_unrecoverable
|
253
|
-
logger.debug { "we're in shutting down state,
|
256
|
+
if @_shutting_down and not (@_closed or is_unrecoverable)
|
257
|
+
logger.debug { "we're in shutting down state, there are #{@reg.in_flight.length} in_flight completions" }
|
254
258
|
|
255
|
-
until @reg.in_flight.empty?
|
259
|
+
until @reg.in_flight.empty? or is_unrecoverable or @_closed
|
256
260
|
zkrb_iterate_event_loop
|
257
261
|
iterate_event_delivery
|
262
|
+
logger.debug { "there are #{@reg.in_flight} in_flight completions left" }
|
258
263
|
end
|
259
264
|
|
260
265
|
logger.debug { "finished completions" }
|
261
266
|
end
|
262
267
|
|
268
|
+
if @_shutting_down # in shutting down state, no more can be added to @reg
|
269
|
+
# anything left over after all that gets the finger
|
270
|
+
remaining = @reg.next_batch + @reg.in_flight.values
|
271
|
+
|
272
|
+
logger.debug { "there are #{remaining.length} completions to awaken" }
|
273
|
+
|
274
|
+
@reg.in_flight.clear
|
275
|
+
|
276
|
+
while cb = remaining.shift
|
277
|
+
cb.shutdown!
|
278
|
+
end
|
279
|
+
end
|
263
280
|
rescue ShuttingDownException
|
264
281
|
logger.error { "event thread saw @_shutting_down, bailing without entering loop" }
|
265
282
|
ensure
|
266
|
-
logger.debug { "
|
283
|
+
logger.debug { "##{__method__} exiting" }
|
267
284
|
end
|
268
285
|
|
269
286
|
def submit_pending_calls
|
@@ -285,7 +302,7 @@ class CZookeeper
|
|
285
302
|
|
286
303
|
def iterate_event_delivery
|
287
304
|
while hash = zkrb_get_next_event_st()
|
288
|
-
logger.debug { "
|
305
|
+
logger.debug { "##{__method__} got #{hash.inspect} " }
|
289
306
|
|
290
307
|
if (hash[:req_id] == ZKRB_GLOBAL_CB_REQ) && (hash[:type] == -1)
|
291
308
|
ev_state = hash[:state]
|
@@ -324,14 +341,14 @@ class CZookeeper
|
|
324
341
|
|
325
342
|
# use this method to set the @_shutting_down flag to true
|
326
343
|
def shut_down!
|
327
|
-
logger.debug { "
|
344
|
+
logger.debug { "##{__method__}" }
|
328
345
|
|
329
346
|
@mutex.synchronize { @_shutting_down = true }
|
330
347
|
end
|
331
348
|
|
332
349
|
# called by underlying C code to signal we're running
|
333
350
|
def zkc_set_running_and_notify!
|
334
|
-
logger.debug { "
|
351
|
+
logger.debug { "##{__method__}" }
|
335
352
|
|
336
353
|
@mutex.synchronize do
|
337
354
|
@_running = true
|
data/lib/zookeeper.rb
CHANGED
data/lib/zookeeper/common.rb
CHANGED
@@ -130,7 +130,7 @@ protected
|
|
130
130
|
def dispatch_next_callback(hash)
|
131
131
|
return nil unless hash
|
132
132
|
|
133
|
-
|
133
|
+
logger.debug { "get_next_event returned: #{prettify_event(hash).inspect}" }
|
134
134
|
|
135
135
|
is_completion = hash.has_key?(:rc)
|
136
136
|
|
@@ -22,7 +22,7 @@ module Zookeeper
|
|
22
22
|
@mutex = Mutex.new
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def synchronize
|
26
26
|
@mutex.lock
|
27
27
|
begin
|
28
28
|
yield self
|
@@ -85,10 +85,6 @@ module Zookeeper
|
|
85
85
|
|
86
86
|
# make this error reporting more robust if necessary, right now, just set to state
|
87
87
|
@error = nil
|
88
|
-
|
89
|
-
# set to true when an event occurs that would cause the caller to
|
90
|
-
# otherwise block forever
|
91
|
-
@interrupt = false
|
92
88
|
end
|
93
89
|
|
94
90
|
# the caller calls this method and receives the response from the async loop
|
@@ -99,6 +95,8 @@ module Zookeeper
|
|
99
95
|
case @error
|
100
96
|
when nil
|
101
97
|
# ok, nothing to see here, carry on
|
98
|
+
when :shutdown
|
99
|
+
raise Exceptions::NotConnected, "the connection is shutting down"
|
102
100
|
when ZOO_EXPIRED_SESSION_STATE
|
103
101
|
raise Exceptions::SessionExpired, "connection has expired"
|
104
102
|
else
|
@@ -162,6 +160,15 @@ module Zookeeper
|
|
162
160
|
@meth == :state
|
163
161
|
end
|
164
162
|
|
163
|
+
# interrupt the sleeping thread with a NotConnected error
|
164
|
+
def shutdown!
|
165
|
+
@mutex.synchronize do
|
166
|
+
return if @rval or @error
|
167
|
+
@error = :shutdown
|
168
|
+
@cond.broadcast
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
165
172
|
protected
|
166
173
|
|
167
174
|
# an args array with the only difference being that if there's a user
|
data/lib/zookeeper/version.rb
CHANGED
data/spec/support/00_logging.rb
CHANGED
@@ -3,12 +3,14 @@ module Zookeeper
|
|
3
3
|
end
|
4
4
|
|
5
5
|
layout = Logging.layouts.pattern(
|
6
|
-
:pattern => '%.1l, [%d #%p]: %m\n',
|
6
|
+
:pattern => '%.1l, [%d #%p] %25.25c{2}: %m\n',
|
7
7
|
:date_pattern => '%Y-%m-%d %H:%M:%S.%6N'
|
8
8
|
)
|
9
9
|
|
10
10
|
appender = (ENV['ZOOKEEPER_DEBUG'] || ENV['ZKRB_DEBUG']) ? Logging.appenders.stderr : Logging.appenders.file(Zookeeper::TEST_LOG_PATH)
|
11
11
|
appender.layout = layout
|
12
|
+
appender.auto_flushing = 25
|
13
|
+
appender.flush_period = 5
|
12
14
|
|
13
15
|
%w[spec Zookeeper].each do |name|
|
14
16
|
::Logging.logger[name].tap do |log|
|
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: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 3
|
10
|
+
version: 1.2.3
|
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-05-
|
23
|
+
date: 2012-05-23 00:00:00 Z
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: backports
|
@@ -193,3 +193,4 @@ test_files:
|
|
193
193
|
- spec/support/progress_formatter.rb
|
194
194
|
- spec/support/zookeeper_spec_helpers.rb
|
195
195
|
- spec/zookeeper_spec.rb
|
196
|
+
has_rdoc:
|