zookeeper 1.2.1-java → 1.2.2-java

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ v1.2.2 avoid race while waiting for connection
2
+
3
+ * There was a possible race in CZookeeper#wait_until_connected where if we
4
+ couldn't connect to the port specified (localhost:28271) then we wound up
5
+ burning 100% CPU and spinning. This solution fixes that by hooking into the
6
+ event delivery and keeping track of what the current state is. When there's
7
+ a change, we use a ConditionVariable to wake up threads that were waiting
8
+ until the connection was connected. Additionally, we now respect the
9
+ timeout parameter again.
10
+
1
11
  v1.2.1 simplify assert_open
2
12
 
3
13
  * The client methods were all calling assert_open before performing an
data/ext/c_zookeeper.rb CHANGED
@@ -70,7 +70,10 @@ class CZookeeper
70
70
  @running_cond = @mutex.new_cond
71
71
 
72
72
  # used to signal we've received the connected event
73
- @connected_cond = @mutex.new_cond
73
+ @state_cond = @mutex.new_cond
74
+
75
+ # the current state of the connection
76
+ @state = ZOO_CLOSED_STATE
74
77
 
75
78
  @pipe_read, @pipe_write = IO.pipe
76
79
 
@@ -167,12 +170,13 @@ class CZookeeper
167
170
  # if timeout is nil, we never time out, and wait forever for CONNECTED state
168
171
  #
169
172
  def wait_until_connected(timeout=10)
170
- # this begin/ensure/end style is recommended by tarceri
171
- # no need to create a context for every mutex grab
172
173
 
173
- wait_until_running(timeout)
174
+ return false unless wait_until_running(timeout)
175
+
176
+ @mutex.synchronize do
177
+ @state_cond.wait(timeout) unless (@state == ZOO_CONNECTED_STATE)
178
+ end
174
179
 
175
- Thread.pass until connected? or is_unrecoverable
176
180
  connected?
177
181
  end
178
182
 
@@ -222,13 +226,10 @@ class CZookeeper
222
226
  #
223
227
  # returns true if we're running, false if we timed out
224
228
  def wait_until_running(timeout=5)
225
- @mutex.lock
226
- begin
229
+ @mutex.synchronize do
227
230
  return true if @_running
228
231
  @running_cond.wait(timeout)
229
232
  !!@_running
230
- ensure
231
- @mutex.unlock rescue nil
232
233
  end
233
234
  end
234
235
 
@@ -286,11 +287,17 @@ class CZookeeper
286
287
  while hash = zkrb_get_next_event_st()
287
288
  logger.debug { "#{self.class}##{__method__} got #{hash.inspect} " }
288
289
 
289
- # notify when we get this event so we know we're connected
290
- if hash.values_at(:req_id, :type, :state) == CONNECTED_EVENT_VALUES[1..2]
291
- notify_connected!
292
- end
290
+ if (hash[:req_id] == ZKRB_GLOBAL_CB_REQ) && (hash[:type] == -1)
291
+ ev_state = hash[:state]
293
292
 
293
+ if @state != ev_state
294
+ @mutex.synchronize do
295
+ @state = ev_state
296
+ @state_cond.broadcast
297
+ end
298
+ end
299
+ end
300
+
294
301
  cntn = @reg.in_flight.delete(hash[:req_id])
295
302
 
296
303
  if cntn and not cntn.user_callback? # this is one of "our" continuations
@@ -307,14 +314,11 @@ class CZookeeper
307
314
  def event_thread_await_running
308
315
  logger.debug { "event_thread waiting until running: #{@_running}" }
309
316
 
310
- @mutex.lock
311
- begin
317
+ @mutex.synchronize do
312
318
  @running_cond.wait_until { @_running or @_shutting_down }
313
319
  logger.debug { "event_thread running: #{@_running}" }
314
320
 
315
321
  raise ShuttingDownException if @_shutting_down
316
- ensure
317
- @mutex.unlock rescue nil
318
322
  end
319
323
  end
320
324
 
@@ -329,22 +333,16 @@ class CZookeeper
329
333
  def zkc_set_running_and_notify!
330
334
  logger.debug { "#{self.class}##{__method__}" }
331
335
 
332
- @mutex.lock
333
- begin
336
+ @mutex.synchronize do
334
337
  @_running = true
335
338
  @running_cond.broadcast
336
- ensure
337
- @mutex.unlock rescue nil
338
339
  end
339
340
  end
340
341
 
341
- def notify_connected!
342
- @mutex.lock
343
- begin
344
- @connected_cond.broadcast
345
- ensure
346
- @mutex.unlock rescue nil
347
- end
348
- end
342
+ # def notify_state_change!
343
+ # @mutex.synchronize do
344
+ # @state_cond.broadcast
345
+ # end
346
+ # end
349
347
  end
350
348
  end
data/java/java_base.rb CHANGED
@@ -405,7 +405,7 @@ class JavaBase
405
405
 
406
406
  def assert_open
407
407
  # XXX don't know how to check for valid session state!
408
- raise ZookeeperException::NotConnected unless connected?
408
+ raise NotConnected unless connected?
409
409
  end
410
410
 
411
411
  # set the watcher object/proc that will receive all global events (such as session/state events)
@@ -1,4 +1,4 @@
1
1
  module Zookeeper
2
- VERSION = '1.2.1'
2
+ VERSION = '1.2.2'
3
3
  DRIVER_VERSION = '3.3.5'
4
4
  end
data/spec/spec_helper.rb CHANGED
@@ -51,3 +51,11 @@ RSpec.configure do |config|
51
51
  end
52
52
  end
53
53
 
54
+ require 'pp'
55
+
56
+ if RUBY_VERSION == '1.9.3'
57
+ trap('USR1') do
58
+ threads = Thread.list.map { |th| th.backtrace }
59
+ pp threads
60
+ end
61
+ end
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: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 1
10
- version: 1.2.1
9
+ - 2
10
+ version: 1.2.2
11
11
  platform: java
12
12
  authors:
13
13
  - Phillip Pearson