zookeeper 1.2.6-java → 1.2.7-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.
- data/CHANGELOG +19 -0
- data/ext/c_zookeeper.rb +19 -10
- data/ext/zookeeper_base.rb +19 -5
- data/lib/zookeeper/common.rb +31 -29
- data/lib/zookeeper/version.rb +1 -1
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
v1.2.7 further lock adjustments, deadlock risk reduction
|
2
|
+
|
3
|
+
* Refactor ZookeeperBase to not hold onto the mutex while waiting
|
4
|
+
for the dispatch thread to exit and the CZookeeper instance to close.
|
5
|
+
Instead, lock, nil out @czk, and unlock (which will cause all calls to
|
6
|
+
raise NotConnected), and then carry on with the shutdown procedure, greatly
|
7
|
+
reducing the chances of a deadlock. Also add a hardcoded 30 second timeout
|
8
|
+
to the join of the shutdown thread, that way we won't hang indefinitely in
|
9
|
+
the case of an unforseen condition.
|
10
|
+
|
11
|
+
* Improve the CZookeeper#wait_until_connected to use a deadline approach
|
12
|
+
to waiting for both running and connected states. Also, handle the
|
13
|
+
'nil' (wait forever) timeout properly.
|
14
|
+
|
15
|
+
* Wake all waiting threads on all ConditionVariables when CZookeeper#shut_down!
|
16
|
+
is called
|
17
|
+
|
18
|
+
v1.2.6 fix build on fedora
|
19
|
+
|
1
20
|
v1.2.5 cleanup locking in ZookeeperBase
|
2
21
|
|
3
22
|
* There were several situations where we would hold the lock before calling
|
data/ext/c_zookeeper.rb
CHANGED
@@ -161,7 +161,7 @@ class CZookeeper
|
|
161
161
|
|
162
162
|
def state
|
163
163
|
return ZOO_CLOSED_STATE if closed?
|
164
|
-
|
164
|
+
@mutex.synchronize { @state }
|
165
165
|
end
|
166
166
|
|
167
167
|
# this implementation is gross, but i don't really see another way of doing it
|
@@ -172,12 +172,22 @@ class CZookeeper
|
|
172
172
|
# if timeout is nil, we never time out, and wait forever for CONNECTED state
|
173
173
|
#
|
174
174
|
def wait_until_connected(timeout=10)
|
175
|
+
time_to_stop = timeout ? Time.now + timeout : nil
|
175
176
|
|
176
177
|
return false unless wait_until_running(timeout)
|
177
178
|
|
178
179
|
@mutex.synchronize do
|
179
|
-
|
180
|
-
|
180
|
+
while true
|
181
|
+
if timeout
|
182
|
+
now = Time.now
|
183
|
+
break if (@state == ZOO_CONNECTED_STATE) || @_shutting_down || @_closed || (now > time_to_stop)
|
184
|
+
delay = time_to_stop.to_f - now.to_f
|
185
|
+
@state_cond.wait(delay)
|
186
|
+
else
|
187
|
+
break if (@state == ZOO_CONNECTED_STATE) || @_shutting_down || @_closed
|
188
|
+
@state_cond.wait
|
189
|
+
end
|
190
|
+
end
|
181
191
|
end
|
182
192
|
|
183
193
|
connected?
|
@@ -343,7 +353,12 @@ class CZookeeper
|
|
343
353
|
def shut_down!
|
344
354
|
logger.debug { "##{__method__}" }
|
345
355
|
|
346
|
-
@mutex.synchronize
|
356
|
+
@mutex.synchronize do
|
357
|
+
@_shutting_down = true
|
358
|
+
# ollie ollie oxen all home free!
|
359
|
+
@state_cond.broadcast
|
360
|
+
@running_cond.broadcast
|
361
|
+
end
|
347
362
|
end
|
348
363
|
|
349
364
|
# called by underlying C code to signal we're running
|
@@ -355,11 +370,5 @@ class CZookeeper
|
|
355
370
|
@running_cond.broadcast
|
356
371
|
end
|
357
372
|
end
|
358
|
-
|
359
|
-
# def notify_state_change!
|
360
|
-
# @mutex.synchronize do
|
361
|
-
# @state_cond.broadcast
|
362
|
-
# end
|
363
|
-
# end
|
364
373
|
end
|
365
374
|
end
|
data/ext/zookeeper_base.rb
CHANGED
@@ -130,20 +130,34 @@ class ZookeeperBase
|
|
130
130
|
# potentially dangerous and should only be called after a fork() to close
|
131
131
|
# this instance
|
132
132
|
def close!
|
133
|
-
@czk
|
133
|
+
inst, @czk = @czk, nil
|
134
|
+
inst && inst.close
|
134
135
|
end
|
135
136
|
|
136
137
|
# close the connection normally, stops the dispatch thread and closes the
|
137
138
|
# underlying connection cleanly
|
138
139
|
def close
|
139
|
-
|
140
|
-
|
140
|
+
sd_thread = nil
|
141
|
+
|
142
|
+
@mutex.synchronize do
|
143
|
+
return unless @czk
|
144
|
+
inst, @czk = @czk, nil
|
145
|
+
|
146
|
+
sd_thread = Thread.new(inst) do |_inst|
|
141
147
|
stop_dispatch_thread!
|
142
|
-
close
|
148
|
+
_inst.close
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# if we're on the event dispatch thread for some stupid reason, then don't join
|
153
|
+
unless event_dispatch_thread?
|
154
|
+
# hard-coded 30 second delay, don't hang forever
|
155
|
+
if sd_thread.join(30) != sd_thread
|
156
|
+
logger.error { "timed out waiting for shutdown thread to exit" }
|
143
157
|
end
|
144
158
|
end
|
145
159
|
|
146
|
-
|
160
|
+
nil
|
147
161
|
end
|
148
162
|
|
149
163
|
# the C lib doesn't strip the chroot path off of returned path values, which
|
data/lib/zookeeper/common.rb
CHANGED
@@ -10,15 +10,7 @@ module Common
|
|
10
10
|
@dispatcher && (@dispatcher == Thread.current)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
def get_next_event(blocking=true)
|
15
|
-
@event_queue.pop(!blocking).tap do |event|
|
16
|
-
logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
|
17
|
-
end
|
18
|
-
rescue ThreadError
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
13
|
+
private
|
22
14
|
def setup_call(meth_name, opts)
|
23
15
|
req_id = nil
|
24
16
|
@mutex.synchronize {
|
@@ -71,21 +63,9 @@ protected
|
|
71
63
|
return
|
72
64
|
end
|
73
65
|
|
74
|
-
logger.debug {
|
75
|
-
|
76
|
-
@dispatcher = Thread.new
|
77
|
-
while true
|
78
|
-
begin
|
79
|
-
dispatch_next_callback(get_next_event(true))
|
80
|
-
rescue QueueWithPipe::ShutdownException
|
81
|
-
logger.info { "dispatch thread exiting, got shutdown exception" }
|
82
|
-
break
|
83
|
-
rescue Exception => e
|
84
|
-
$stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
|
85
|
-
end
|
86
|
-
end
|
87
|
-
signal_dispatch_thread_exit!
|
88
|
-
end
|
66
|
+
logger.debug { "starting dispatch thread" }
|
67
|
+
|
68
|
+
@dispatcher = Thread.new(&method(:dispatch_thread_body))
|
89
69
|
end
|
90
70
|
end
|
91
71
|
|
@@ -120,11 +100,12 @@ protected
|
|
120
100
|
end
|
121
101
|
end
|
122
102
|
|
123
|
-
def
|
124
|
-
@
|
125
|
-
logger.debug { "
|
126
|
-
@dispatch_shutdown_cond.broadcast
|
103
|
+
def get_next_event(blocking=true)
|
104
|
+
@event_queue.pop(!blocking).tap do |event|
|
105
|
+
logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
|
127
106
|
end
|
107
|
+
rescue ThreadError
|
108
|
+
nil
|
128
109
|
end
|
129
110
|
|
130
111
|
def dispatch_next_callback(hash)
|
@@ -177,7 +158,28 @@ protected
|
|
177
158
|
end
|
178
159
|
end
|
179
160
|
|
180
|
-
|
161
|
+
def dispatch_thread_body
|
162
|
+
while true
|
163
|
+
begin
|
164
|
+
dispatch_next_callback(get_next_event(true))
|
165
|
+
rescue QueueWithPipe::ShutdownException
|
166
|
+
logger.info { "dispatch thread exiting, got shutdown exception" }
|
167
|
+
return
|
168
|
+
rescue Exception => e
|
169
|
+
$stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
ensure
|
173
|
+
signal_dispatch_thread_exit!
|
174
|
+
end
|
175
|
+
|
176
|
+
def signal_dispatch_thread_exit!
|
177
|
+
@mutex.synchronize do
|
178
|
+
logger.debug { "dispatch thread exiting!" }
|
179
|
+
@dispatch_shutdown_cond.broadcast
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
181
183
|
def prettify_event(hash)
|
182
184
|
hash.dup.tap do |h|
|
183
185
|
# pretty up the event display
|
data/lib/zookeeper/version.rb
CHANGED
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: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 7
|
10
|
+
version: 1.2.7
|
11
11
|
platform: java
|
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-06-
|
23
|
+
date: 2012-06-05 00:00:00 Z
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: backports
|