zk 1.5.2 → 1.5.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/Guardfile +10 -1
- data/lib/zk/client/base.rb +2 -4
- data/lib/zk/client/state_mixin.rb +1 -1
- data/lib/zk/client/threaded.rb +140 -48
- data/lib/zk/election.rb +3 -3
- data/lib/zk/event_handler.rb +1 -5
- data/lib/zk/event_handler_subscription/base.rb +1 -1
- data/lib/zk/locker/exclusive_locker.rb +1 -1
- data/lib/zk/locker/locker_base.rb +1 -1
- data/lib/zk/locker/shared_locker.rb +1 -1
- data/lib/zk/mongoid.rb +1 -0
- data/lib/zk/pool.rb +2 -2
- data/lib/zk/subscription.rb +1 -1
- data/lib/zk/threaded_callback.rb +2 -2
- data/lib/zk/version.rb +1 -1
- data/spec/shared/client_contexts.rb +4 -9
- data/spec/shared/client_examples.rb +9 -4
- data/spec/spec_helper.rb +3 -1
- data/spec/support/logging.rb +3 -4
- metadata +3 -3
    
        data/Guardfile
    CHANGED
    
    | @@ -26,11 +26,20 @@ guard 'rspec', :version => 2 do | |
| 26 26 | 
             
                when %r{^(?:zk/locker/locker_base|spec/shared/locker)}
         | 
| 27 27 | 
             
                  Dir["spec/zk/locker/*_spec.rb"]
         | 
| 28 28 |  | 
| 29 | 
            +
                when %r{^zk/client/(?:base|state_mixin)}
         | 
| 30 | 
            +
                  Dir['spec/zk/{client,client/*,zookeeper}_spec.rb']
         | 
| 31 | 
            +
             | 
| 29 32 | 
             
                when 'zk' # .rb
         | 
| 30 33 | 
             
                  'spec'  # run all tests
         | 
| 31 34 |  | 
| 32 35 | 
             
                else
         | 
| 33 | 
            -
                  "spec/#{m[1]}_spec.rb"
         | 
| 36 | 
            +
                  generic = "spec/#{m[1]}_spec.rb"
         | 
| 37 | 
            +
                  if test(?f, generic)
         | 
| 38 | 
            +
                    generic
         | 
| 39 | 
            +
                  else
         | 
| 40 | 
            +
                    $stderr.puts "RUNNING ALL TESTS"
         | 
| 41 | 
            +
                    'spec'
         | 
| 42 | 
            +
                  end
         | 
| 34 43 | 
             
                end
         | 
| 35 44 | 
             
              end
         | 
| 36 45 |  | 
    
        data/lib/zk/client/base.rb
    CHANGED
    
    | @@ -51,7 +51,7 @@ module ZK | |
| 51 51 | 
             
                  # the wrapped connection object
         | 
| 52 52 | 
             
                  # @private 
         | 
| 53 53 | 
             
                  attr_reader :cnx
         | 
| 54 | 
            -
                   | 
| 54 | 
            +
                  private :cnx
         | 
| 55 55 |  | 
| 56 56 | 
             
                  # maps from a symbol given as an option, to the numeric error constant that should
         | 
| 57 57 | 
             
                  # not raise an exception
         | 
| @@ -1020,7 +1020,7 @@ module ZK | |
| 1020 1020 | 
             
                  def raw_event_handler(event)
         | 
| 1021 1021 | 
             
                  end
         | 
| 1022 1022 |  | 
| 1023 | 
            -
                   | 
| 1023 | 
            +
                  private
         | 
| 1024 1024 | 
             
                    # does the current pid match the one that created us?
         | 
| 1025 1025 | 
             
                    def forked?
         | 
| 1026 1026 | 
             
                      Process.pid != @pid
         | 
| @@ -1038,7 +1038,6 @@ module ZK | |
| 1038 1038 | 
             
                      check_rc(rv, opts)
         | 
| 1039 1039 | 
             
                    end
         | 
| 1040 1040 |  | 
| 1041 | 
            -
                    # @private
         | 
| 1042 1041 | 
             
                    # XXX: make this actually call the method on cnx
         | 
| 1043 1042 | 
             
                    def check_rc(rv_hash, inputs)
         | 
| 1044 1043 | 
             
                      code  = rv_hash[:rc]
         | 
| @@ -1078,7 +1077,6 @@ module ZK | |
| 1078 1077 | 
             
                      Set.new(ERROR_IGNORE_MAP.values_at(*sym_array))
         | 
| 1079 1078 | 
             
                    end
         | 
| 1080 1079 |  | 
| 1081 | 
            -
                    # @private
         | 
| 1082 1080 | 
             
                    def setup_watcher!(watch_type, opts, &b)
         | 
| 1083 1081 | 
             
                      event_handler.setup_watcher!(watch_type, opts, &b)
         | 
| 1084 1082 | 
             
                    end
         | 
    
        data/lib/zk/client/threaded.rb
    CHANGED
    
    | @@ -45,10 +45,10 @@ module ZK | |
| 45 45 |  | 
| 46 46 | 
             
                  # @private
         | 
| 47 47 | 
             
                  module Constants
         | 
| 48 | 
            -
                     | 
| 49 | 
            -
                     | 
| 50 | 
            -
                     | 
| 51 | 
            -
                     | 
| 48 | 
            +
                    RUNNING   = :running
         | 
| 49 | 
            +
                    PAUSED    = :paused
         | 
| 50 | 
            +
                    CLOSE_REQ = :close_requested
         | 
| 51 | 
            +
                    CLOSED    = :closed
         | 
| 52 52 | 
             
                  end
         | 
| 53 53 | 
             
                  include Constants
         | 
| 54 54 |  | 
| @@ -161,13 +161,12 @@ module ZK | |
| 161 161 |  | 
| 162 162 | 
             
                    @reconnect = opts.fetch(:reconnect, true)
         | 
| 163 163 |  | 
| 164 | 
            -
                     | 
| 165 | 
            -
                    @cond = @mutex.new_cond
         | 
| 164 | 
            +
                    setup_locks
         | 
| 166 165 |  | 
| 167 | 
            -
                    @ | 
| 166 | 
            +
                    @client_state = RUNNING # this is to distinguish between *our* state and the underlying connection state
         | 
| 168 167 |  | 
| 169 168 | 
             
                    # this is the last status update we've received from the underlying connection
         | 
| 170 | 
            -
                    @last_cnx_state =  | 
| 169 | 
            +
                    @last_cnx_state = nil
         | 
| 171 170 |  | 
| 172 171 | 
             
                    @retry_duration = opts.fetch(:retry_duration, nil).to_i
         | 
| 173 172 |  | 
| @@ -183,6 +182,15 @@ module ZK | |
| 183 182 |  | 
| 184 183 | 
             
                    connect if opts.fetch(:connect, true)
         | 
| 185 184 | 
             
                  end
         | 
| 185 | 
            +
                  
         | 
| 186 | 
            +
                  # ensure that the initializer and the reopen code set up the mutexes
         | 
| 187 | 
            +
                  # the same way (i.e. use a Monitor or a Mutex, no, really, I screwed 
         | 
| 188 | 
            +
                  # this up once) 
         | 
| 189 | 
            +
                  def setup_locks
         | 
| 190 | 
            +
                    @mutex = Monitor.new
         | 
| 191 | 
            +
                    @cond = @mutex.new_cond
         | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
                  private :setup_locks
         | 
| 186 194 |  | 
| 187 195 | 
             
                  # @private
         | 
| 188 196 | 
             
                  def self.finalizer(hooks)
         | 
| @@ -206,14 +214,18 @@ module ZK | |
| 206 214 |  | 
| 207 215 | 
             
                      logger.debug { "reopening everything, fork detected!" }
         | 
| 208 216 |  | 
| 209 | 
            -
                       | 
| 210 | 
            -
             | 
| 217 | 
            +
                      setup_locks
         | 
| 218 | 
            +
             | 
| 211 219 | 
             
                      @pid        = Process.pid
         | 
| 212 | 
            -
                      @ | 
| 220 | 
            +
                      @client_state  = RUNNING                     # reset state to running if we were paused
         | 
| 213 221 |  | 
| 214 222 | 
             
                      old_cnx, @cnx = @cnx, nil
         | 
| 215 223 | 
             
                      old_cnx.close! if old_cnx # && !old_cnx.closed?
         | 
| 216 224 |  | 
| 225 | 
            +
                      join_and_clear_reconnect_thread
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                      @last_cnx_state = nil
         | 
| 228 | 
            +
             | 
| 217 229 | 
             
                      @mutex.synchronize do
         | 
| 218 230 | 
             
                        # it's important that we're holding the lock, as access to 'cnx' is
         | 
| 219 231 | 
             
                        # synchronized, and we want to avoid a race where event handlers
         | 
| @@ -228,11 +240,12 @@ module ZK | |
| 228 240 | 
             
                      end
         | 
| 229 241 | 
             
                    else
         | 
| 230 242 | 
             
                      @mutex.synchronize do
         | 
| 231 | 
            -
                        if @ | 
| 243 | 
            +
                        if @client_state == PAUSED
         | 
| 232 244 | 
             
                          # XXX: what to do in this case? does it matter?
         | 
| 233 245 | 
             
                        end
         | 
| 234 246 |  | 
| 235 247 | 
             
                        logger.debug { "reopening, no fork detected" }
         | 
| 248 | 
            +
                        @last_cnx_state = nil
         | 
| 236 249 | 
             
                        @cnx.reopen(timeout)                # ok, we werent' forked, so just reopen
         | 
| 237 250 | 
             
                      end
         | 
| 238 251 | 
             
                    end
         | 
| @@ -252,30 +265,37 @@ module ZK | |
| 252 265 | 
             
                  # @private
         | 
| 253 266 | 
             
                  def pause_before_fork_in_parent
         | 
| 254 267 | 
             
                    @mutex.synchronize do
         | 
| 255 | 
            -
                      raise InvalidStateError, "client must be running? when you call #{__method__}" unless (@ | 
| 256 | 
            -
                      @ | 
| 268 | 
            +
                      raise InvalidStateError, "client must be running? when you call #{__method__}" unless (@client_state == RUNNING)
         | 
| 269 | 
            +
                      @client_state = PAUSED
         | 
| 257 270 |  | 
| 258 271 | 
             
                      logger.debug { "#{self.class}##{__method__}" }
         | 
| 259 272 |  | 
| 260 273 | 
             
                      @cond.broadcast
         | 
| 261 274 | 
             
                    end
         | 
| 262 275 |  | 
| 276 | 
            +
                    join_and_clear_reconnect_thread
         | 
| 277 | 
            +
             | 
| 263 278 | 
             
                    # the compact is here because the @cnx *may* be nil when this callback is fired by the
         | 
| 264 279 | 
             
                    # ForkHook (in the case of ZK.open). The race is between the GC calling the finalizer
         | 
| 265 280 | 
             
                    [@event_handler, @threadpool, @cnx].compact.each(&:pause_before_fork_in_parent)
         | 
| 266 281 | 
             
                  ensure
         | 
| 267 | 
            -
                    logger.debug { " | 
| 282 | 
            +
                    logger.debug { "##{__method__} returning" }
         | 
| 268 283 | 
             
                  end
         | 
| 269 284 |  | 
| 270 285 | 
             
                  # @private
         | 
| 271 286 | 
             
                  def resume_after_fork_in_parent
         | 
| 272 287 | 
             
                    @mutex.synchronize do
         | 
| 273 | 
            -
                      raise InvalidStateError, "client must be paused? when you call #{__method__}" unless (@ | 
| 274 | 
            -
                      @ | 
| 288 | 
            +
                      raise InvalidStateError, "client must be paused? when you call #{__method__}" unless (@client_state == PAUSED)
         | 
| 289 | 
            +
                      @client_state = RUNNING
         | 
| 275 290 |  | 
| 276 | 
            -
                      logger.debug { " | 
| 291 | 
            +
                      logger.debug { "##{__method__}" }
         | 
| 277 292 |  | 
| 278 | 
            -
                       | 
| 293 | 
            +
                      if @cnx
         | 
| 294 | 
            +
                        @cnx.resume_after_fork_in_parent
         | 
| 295 | 
            +
                        spawn_reconnect_thread
         | 
| 296 | 
            +
                      end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                      [@event_handler, @threadpool].compact.each(&:resume_after_fork_in_parent)
         | 
| 279 299 |  | 
| 280 300 | 
             
                      @cond.broadcast
         | 
| 281 301 | 
             
                    end
         | 
| @@ -291,12 +311,14 @@ module ZK | |
| 291 311 | 
             
                  #
         | 
| 292 312 | 
             
                  def close!
         | 
| 293 313 | 
             
                    @mutex.synchronize do 
         | 
| 294 | 
            -
                      return if [:closed, :close_requested].include?(@ | 
| 314 | 
            +
                      return if [:closed, :close_requested].include?(@client_state)
         | 
| 295 315 | 
             
                      logger.debug { "moving to :close_requested state" }
         | 
| 296 | 
            -
                      @ | 
| 316 | 
            +
                      @client_state = CLOSE_REQ
         | 
| 297 317 | 
             
                      @cond.broadcast
         | 
| 298 318 | 
             
                    end
         | 
| 299 319 |  | 
| 320 | 
            +
                    join_and_clear_reconnect_thread
         | 
| 321 | 
            +
             | 
| 300 322 | 
             
                    on_tpool = on_threadpool?
         | 
| 301 323 |  | 
| 302 324 | 
             
                    # Ok, so the threadpool will wait up to N seconds while joining each thread.
         | 
| @@ -308,6 +330,7 @@ module ZK | |
| 308 330 | 
             
                    # and wait for it to exit
         | 
| 309 331 | 
             
                    #
         | 
| 310 332 | 
             
                    shutdown_thread = Thread.new do
         | 
| 333 | 
            +
                      Thread.current[:name] = 'shutdown'
         | 
| 311 334 | 
             
                      @threadpool.shutdown(10)
         | 
| 312 335 |  | 
| 313 336 | 
             
                      # this will call #close
         | 
| @@ -315,7 +338,8 @@ module ZK | |
| 315 338 |  | 
| 316 339 | 
             
                      @mutex.synchronize do
         | 
| 317 340 | 
             
                        logger.debug { "moving to :closed state" }
         | 
| 318 | 
            -
                        @ | 
| 341 | 
            +
                        @client_state = CLOSED
         | 
| 342 | 
            +
                        @last_cnx_state = nil
         | 
| 319 343 | 
             
                        @cond.broadcast
         | 
| 320 344 | 
             
                      end
         | 
| 321 345 | 
             
                    end
         | 
| @@ -348,15 +372,6 @@ module ZK | |
| 348 372 | 
             
                    @mutex.synchronize do
         | 
| 349 373 | 
             
                      @last_cnx_state = event.state
         | 
| 350 374 |  | 
| 351 | 
            -
                      if event.client_invalid? and @reconnect and not dead_or_dying?
         | 
| 352 | 
            -
                        logger.error { "Got event #{event.state_name}, calling reopen(0)! things may be messed up until this works itself out!" }
         | 
| 353 | 
            -
             | 
| 354 | 
            -
                        # reopen(0) means that we don't want to wait for the connection
         | 
| 355 | 
            -
                        # to reach the connected state before returning as we're on the
         | 
| 356 | 
            -
                        # event thread.
         | 
| 357 | 
            -
                        reopen(0)
         | 
| 358 | 
            -
                      end
         | 
| 359 | 
            -
             | 
| 360 375 | 
             
                      @cond.broadcast # wake anyone waiting for a connection state update
         | 
| 361 376 | 
             
                    end
         | 
| 362 377 | 
             
                  rescue Exception => e
         | 
| @@ -364,26 +379,47 @@ module ZK | |
| 364 379 | 
             
                  end
         | 
| 365 380 |  | 
| 366 381 | 
             
                  def closed?
         | 
| 367 | 
            -
                    return true if @mutex.synchronize { @ | 
| 382 | 
            +
                    return true if @mutex.synchronize { @client_state == CLOSED }
         | 
| 368 383 | 
             
                    super
         | 
| 369 384 | 
             
                  end
         | 
| 370 385 |  | 
| 371 386 | 
             
                  # are we in running (not-paused) state?
         | 
| 387 | 
            +
                  # @private
         | 
| 372 388 | 
             
                  def running?
         | 
| 373 | 
            -
                    @mutex.synchronize { @ | 
| 389 | 
            +
                    @mutex.synchronize { @client_state == RUNNING }
         | 
| 374 390 | 
             
                  end
         | 
| 375 391 |  | 
| 376 392 | 
             
                  # are we in paused state?
         | 
| 393 | 
            +
                  # @private
         | 
| 377 394 | 
             
                  def paused?
         | 
| 378 | 
            -
                    @mutex.synchronize { @ | 
| 395 | 
            +
                    @mutex.synchronize { @client_state == PAUSED }
         | 
| 379 396 | 
             
                  end
         | 
| 380 397 |  | 
| 381 398 | 
             
                  # has shutdown time arrived?
         | 
| 399 | 
            +
                  # @private
         | 
| 382 400 | 
             
                  def close_requested?
         | 
| 383 | 
            -
                    @mutex.synchronize { @ | 
| 401 | 
            +
                    @mutex.synchronize { @client_state == CLOSE_REQ }
         | 
| 384 402 | 
             
                  end
         | 
| 385 403 |  | 
| 386 | 
            -
                   | 
| 404 | 
            +
                  # @private
         | 
| 405 | 
            +
                  def wait_until_connected_or_dying(timeout)
         | 
| 406 | 
            +
                    time_to_stop = Time.now + timeout
         | 
| 407 | 
            +
             | 
| 408 | 
            +
                    @mutex.synchronize do
         | 
| 409 | 
            +
                      while (@last_cnx_state != Zookeeper::ZOO_CONNECTED_STATE) && (Time.now < time_to_stop) && (@client_state == RUNNING)
         | 
| 410 | 
            +
                        @cond.wait(timeout)
         | 
| 411 | 
            +
                      end
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                      logger.debug { "@last_cnx_state: #{@last_cnx_state.inspect}, time_left? #{Time.now.to_f < time_to_stop.to_f}, @client_state: #{@client_state.inspect}" }
         | 
| 414 | 
            +
                    end
         | 
| 415 | 
            +
                  end
         | 
| 416 | 
            +
             | 
| 417 | 
            +
                  private
         | 
| 418 | 
            +
                    # this is just here so we can see it in stack traces
         | 
| 419 | 
            +
                    def reopen_after_session_expired
         | 
| 420 | 
            +
                      reopen
         | 
| 421 | 
            +
                    end
         | 
| 422 | 
            +
                    
         | 
| 387 423 | 
             
                    # in the threaded version of the client, synchronize access around cnx
         | 
| 388 424 | 
             
                    # so that callers don't wind up with a nil object when we're in the middle
         | 
| 389 425 | 
             
                    # of reopening it
         | 
| @@ -391,6 +427,58 @@ module ZK | |
| 391 427 | 
             
                      @mutex.synchronize { @cnx }
         | 
| 392 428 | 
             
                    end
         | 
| 393 429 |  | 
| 430 | 
            +
                    def reconnect_thread_body
         | 
| 431 | 
            +
                      Thread.current[:name] = 'reconnect'
         | 
| 432 | 
            +
                      while @reconnect  # too clever?
         | 
| 433 | 
            +
                        @mutex.synchronize do
         | 
| 434 | 
            +
                          # either we havne't seen a valid session update from this
         | 
| 435 | 
            +
                          # connection yet, or we're doing fine, so just wait
         | 
| 436 | 
            +
                          @cond.wait_while { !seen_session_state_event? or (valid_session_state? and (@client_state == RUNNING)) }
         | 
| 437 | 
            +
             | 
| 438 | 
            +
                          # we've entered into a non-running state, so we exit
         | 
| 439 | 
            +
                          # note: need to restart this thread after a fork in parent
         | 
| 440 | 
            +
                          if @client_state != RUNNING
         | 
| 441 | 
            +
                            logger.debug { "session failure watcher thread exiting, @client_state: #{@client_state}" }
         | 
| 442 | 
            +
                            return
         | 
| 443 | 
            +
                          end
         | 
| 444 | 
            +
             | 
| 445 | 
            +
                          # if we know that this session was valid once and it has now
         | 
| 446 | 
            +
                          # become invalid we call reopen
         | 
| 447 | 
            +
                          #
         | 
| 448 | 
            +
                          if seen_session_state_event? and not valid_session_state?
         | 
| 449 | 
            +
                            logger.debug { "session state was invalid, calling reopen" }
         | 
| 450 | 
            +
             | 
| 451 | 
            +
                            # reopen will reset @last_cnx_state so that
         | 
| 452 | 
            +
                            # seen_session_state_event? will return false until the first
         | 
| 453 | 
            +
                            # event has been delivered on the new connection
         | 
| 454 | 
            +
                            rv = reopen_after_session_expired
         | 
| 455 | 
            +
             | 
| 456 | 
            +
                            logger.debug { "reopen returned: #{rv.inspect}" }
         | 
| 457 | 
            +
                          end
         | 
| 458 | 
            +
                        end
         | 
| 459 | 
            +
                      end
         | 
| 460 | 
            +
                    ensure
         | 
| 461 | 
            +
                      logger.debug { "reconnect thread exiting" }
         | 
| 462 | 
            +
                    end
         | 
| 463 | 
            +
             | 
| 464 | 
            +
                    def join_and_clear_reconnect_thread
         | 
| 465 | 
            +
                      return unless @reconnect_thread
         | 
| 466 | 
            +
                      begin
         | 
| 467 | 
            +
                         # this should never time out but, just to make sure we don't hang forever
         | 
| 468 | 
            +
                        unless @reconnect_thread.join(30)
         | 
| 469 | 
            +
                          logger.error { "timed out waiting for reconnect thread to join! something is hosed!" }
         | 
| 470 | 
            +
                        end
         | 
| 471 | 
            +
                      rescue Exception => e
         | 
| 472 | 
            +
                        logger.error { "caught exception joining reconnect thread" }
         | 
| 473 | 
            +
                        logger.error { e.to_std_format }
         | 
| 474 | 
            +
                      end
         | 
| 475 | 
            +
                      @reconnect_thread = nil
         | 
| 476 | 
            +
                    end
         | 
| 477 | 
            +
             | 
| 478 | 
            +
                    def spawn_reconnect_thread
         | 
| 479 | 
            +
                      @reconnect_thread ||= Thread.new(&method(:reconnect_thread_body))
         | 
| 480 | 
            +
                    end
         | 
| 481 | 
            +
             | 
| 394 482 | 
             
                    def call_and_check_rc(meth, opts)
         | 
| 395 483 | 
             
                      if retry_duration = (opts.delete(:retry_duration) || @retry_duration)
         | 
| 396 484 | 
             
                        begin
         | 
| @@ -400,7 +488,7 @@ module ZK | |
| 400 488 |  | 
| 401 489 | 
             
                          wait_until_connected_or_dying(retry_duration)
         | 
| 402 490 |  | 
| 403 | 
            -
                          if (@last_cnx_state != Zookeeper::ZOO_CONNECTED_STATE) || (Time.now > time_to_stop) || (@ | 
| 491 | 
            +
                          if (@last_cnx_state != Zookeeper::ZOO_CONNECTED_STATE) || (Time.now > time_to_stop) || (@client_state != RUNNING)
         | 
| 404 492 | 
             
                            raise e
         | 
| 405 493 | 
             
                          else
         | 
| 406 494 | 
             
                            retry
         | 
| @@ -411,16 +499,20 @@ module ZK | |
| 411 499 | 
             
                      end
         | 
| 412 500 | 
             
                    end
         | 
| 413 501 |  | 
| 414 | 
            -
                     | 
| 415 | 
            -
             | 
| 416 | 
            -
             | 
| 417 | 
            -
                       | 
| 418 | 
            -
             | 
| 419 | 
            -
                          @cond.wait(timeout)
         | 
| 420 | 
            -
                        end
         | 
| 502 | 
            +
                    # have we gotten a status event for the current connection?
         | 
| 503 | 
            +
                    # this method is not synchronized
         | 
| 504 | 
            +
                    def seen_session_state_event?
         | 
| 505 | 
            +
                      !!@last_cnx_state
         | 
| 506 | 
            +
                    end
         | 
| 421 507 |  | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 508 | 
            +
                    # we've seen a session state from the cnx, and it was not "omg we're screwed"
         | 
| 509 | 
            +
                    # will return false if we havne't gotten a session event yet
         | 
| 510 | 
            +
                    #
         | 
| 511 | 
            +
                    # this method is not synchronized
         | 
| 512 | 
            +
                    def valid_session_state?
         | 
| 513 | 
            +
                      # this is kind of icky, but the SESSION_INVALID and AUTH_FAILED states
         | 
| 514 | 
            +
                      # are both negative numbers
         | 
| 515 | 
            +
                      @last_cnx_state and (@last_cnx_state >= 0)
         | 
| 424 516 | 
             
                    end
         | 
| 425 517 |  | 
| 426 518 | 
             
                    def create_connection(*args)
         | 
| @@ -428,14 +520,14 @@ module ZK | |
| 428 520 | 
             
                    end
         | 
| 429 521 |  | 
| 430 522 | 
             
                    def dead_or_dying?
         | 
| 431 | 
            -
                      (@ | 
| 523 | 
            +
                      (@client_state == CLOSE_REQ) || (@client_state == CLOSED)
         | 
| 432 524 | 
             
                    end
         | 
| 433 525 |  | 
| 434 | 
            -
                  private
         | 
| 435 526 | 
             
                    def unlocked_connect(opts={})
         | 
| 436 527 | 
             
                      return if @cnx
         | 
| 437 528 | 
             
                      timeout = opts.fetch(:timeout, @connection_timeout)
         | 
| 438 529 | 
             
                      @cnx = create_connection(@host, timeout, @event_handler.get_default_watcher_block)
         | 
| 530 | 
            +
                      spawn_reconnect_thread
         | 
| 439 531 | 
             
                    end
         | 
| 440 532 | 
             
                end
         | 
| 441 533 | 
             
              end
         | 
    
        data/lib/zk/election.rb
    CHANGED
    
    | @@ -150,7 +150,7 @@ module ZK | |
| 150 150 | 
             
                    end
         | 
| 151 151 | 
             
                  end
         | 
| 152 152 |  | 
| 153 | 
            -
                   | 
| 153 | 
            +
                  private
         | 
| 154 154 | 
             
                    def create_root_path!
         | 
| 155 155 | 
             
                      @zk.mkdir_p(root_vote_path)
         | 
| 156 156 | 
             
                    end
         | 
| @@ -244,7 +244,7 @@ module ZK | |
| 244 244 | 
             
                    end
         | 
| 245 245 | 
             
                  end
         | 
| 246 246 |  | 
| 247 | 
            -
                   | 
| 247 | 
            +
                  private
         | 
| 248 248 | 
             
                    # the inauguration, as it were
         | 
| 249 249 | 
             
                    def acknowledge_win!
         | 
| 250 250 | 
             
                      @zk.create(leader_ack_path, @data, :ephemeral => true) 
         | 
| @@ -411,7 +411,7 @@ module ZK | |
| 411 411 | 
             
                    end
         | 
| 412 412 | 
             
                  end
         | 
| 413 413 |  | 
| 414 | 
            -
                   | 
| 414 | 
            +
                  private
         | 
| 415 415 | 
             
                    def the_king_is_dead
         | 
| 416 416 | 
             
                      synchronize do
         | 
| 417 417 | 
             
                        safe_call(*@leader_death_cbs)
         | 
    
        data/lib/zk/event_handler.rb
    CHANGED
    
    | @@ -196,7 +196,6 @@ module ZK | |
| 196 196 | 
             
                  end
         | 
| 197 197 |  | 
| 198 198 | 
             
                public
         | 
| 199 | 
            -
             | 
| 200 199 | 
             
                # used during shutdown to clear registered listeners
         | 
| 201 200 | 
             
                # @private
         | 
| 202 201 | 
             
                def clear! #:nodoc:
         | 
| @@ -303,13 +302,11 @@ module ZK | |
| 303 302 | 
             
                  end
         | 
| 304 303 | 
             
                end
         | 
| 305 304 |  | 
| 306 | 
            -
                 | 
| 307 | 
            -
                  # @private
         | 
| 305 | 
            +
                private
         | 
| 308 306 | 
             
                  def watcher_callback
         | 
| 309 307 | 
             
                    Zookeeper::Callbacks::WatcherCallback.create { |event| process(event) }
         | 
| 310 308 | 
             
                  end
         | 
| 311 309 |  | 
| 312 | 
            -
                  # @private
         | 
| 313 310 | 
             
                  def state_key(arg)
         | 
| 314 311 | 
             
                    int = 
         | 
| 315 312 | 
             
                      case arg
         | 
| @@ -326,7 +323,6 @@ module ZK | |
| 326 323 | 
             
                    raise ArgumentError, "#{arg} is not a valid zookeeper state", caller
         | 
| 327 324 | 
             
                  end
         | 
| 328 325 |  | 
| 329 | 
            -
                  # @private
         | 
| 330 326 | 
             
                  def safe_call(callbacks, *args)
         | 
| 331 327 | 
             
                    callbacks.each do |cb|
         | 
| 332 328 | 
             
                      next unless cb.respond_to?(:call)
         | 
    
        data/lib/zk/mongoid.rb
    CHANGED
    
    
    
        data/lib/zk/pool.rb
    CHANGED
    
    | @@ -140,7 +140,7 @@ module ZK | |
| 140 140 | 
             
                    @state
         | 
| 141 141 | 
             
                  end
         | 
| 142 142 |  | 
| 143 | 
            -
                   | 
| 143 | 
            +
                  private
         | 
| 144 144 | 
             
                    def synchronize
         | 
| 145 145 | 
             
                      @mutex.synchronize { yield }
         | 
| 146 146 | 
             
                    end
         | 
| @@ -255,7 +255,7 @@ module ZK | |
| 255 255 | 
             
                    @mutex.synchronize { @connections.size < @max_clients }
         | 
| 256 256 | 
             
                  end
         | 
| 257 257 |  | 
| 258 | 
            -
                   | 
| 258 | 
            +
                  private
         | 
| 259 259 | 
             
                    def populate_pool!(num_cnx)
         | 
| 260 260 | 
             
                      num_cnx.times { add_connection! }
         | 
| 261 261 | 
             
                    end
         | 
    
        data/lib/zk/subscription.rb
    CHANGED
    
    
    
        data/lib/zk/threaded_callback.rb
    CHANGED
    
    | @@ -116,7 +116,7 @@ module ZK | |
| 116 116 | 
             
                  end
         | 
| 117 117 | 
             
                end
         | 
| 118 118 |  | 
| 119 | 
            -
                 | 
| 119 | 
            +
                private
         | 
| 120 120 | 
             
                  # intentionally *not* synchronized
         | 
| 121 121 | 
             
                  def spawn_dispatch_thread
         | 
| 122 122 | 
             
                    @thread = Thread.new(&method(:dispatch_thread_body))
         | 
| @@ -133,7 +133,7 @@ module ZK | |
| 133 133 | 
             
                        @cond.wait(@mutex) while @array.empty? and @state == :running
         | 
| 134 134 |  | 
| 135 135 | 
             
                        if @state != :running
         | 
| 136 | 
            -
                          logger. | 
| 136 | 
            +
                          logger.debug { "ThreadedCallback, state is #{@state.inspect}, returning" } 
         | 
| 137 137 | 
             
                          return 
         | 
| 138 138 | 
             
                        end
         | 
| 139 139 |  | 
    
        data/lib/zk/version.rb
    CHANGED
    
    
| @@ -24,16 +24,11 @@ shared_context 'threaded client connection' do | |
| 24 24 | 
             
            #     raise @threadpool_exception if @threadpool_exception
         | 
| 25 25 | 
             
            #     logger.debug { "threaded client connection - after hook" }
         | 
| 26 26 |  | 
| 27 | 
            -
                if @zk.closed?
         | 
| 28 | 
            -
                  logger.debug { "zk was closed, calling reopen" }
         | 
| 29 | 
            -
                  @zk.reopen 
         | 
| 30 | 
            -
                end
         | 
| 27 | 
            +
                @zk.close! if @zk and not @zk.closed?
         | 
| 31 28 |  | 
| 32 | 
            -
                 | 
| 33 | 
            -
             | 
| 34 | 
            -
                 | 
| 35 | 
            -
                @zk.close!
         | 
| 36 | 
            -
                wait_until(5) { @zk.closed? }
         | 
| 29 | 
            +
                ZK.open(*connection_args) do |z|
         | 
| 30 | 
            +
                  z.rm_rf(@base_path)
         | 
| 31 | 
            +
                end
         | 
| 37 32 |  | 
| 38 33 | 
             
            #     logger.debug { "threaded client connection - end after hook" }
         | 
| 39 34 | 
             
              end
         | 
| @@ -298,15 +298,20 @@ shared_examples_for 'client' do | |
| 298 298 |  | 
| 299 299 | 
             
              describe 'reconnection' do
         | 
| 300 300 | 
             
                it %[should if it receives a client_invalid? event] do
         | 
| 301 | 
            -
                   | 
| 302 | 
            -
                    m.should_receive(:reopen).with(0).once
         | 
| 303 | 
            -
                  end
         | 
| 301 | 
            +
                  logger.debug { "about to cause the reconnection" }
         | 
| 304 302 |  | 
| 305 303 | 
             
                  props = { :session_event? => true, :client_invalid? => true, :state_name => 'ZOO_EXPIRED_SESSION_STATE', :state => Zookeeper::ZOO_EXPIRED_SESSION_STATE }
         | 
| 306 304 |  | 
| 307 305 | 
             
                  bogus_event = flexmock(:expired_session_event, props)
         | 
| 308 306 |  | 
| 309 | 
            -
                   | 
| 307 | 
            +
                  th = Thread.new do
         | 
| 308 | 
            +
                    @zk.raw_event_handler(bogus_event)
         | 
| 309 | 
            +
                  end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                  @zk.wait_until_connected_or_dying(5)
         | 
| 312 | 
            +
                  @zk.should be_connected
         | 
| 313 | 
            +
             | 
| 314 | 
            +
                  th.join(2).should == th
         | 
| 310 315 | 
             
                end
         | 
| 311 316 | 
             
              end # reconnection
         | 
| 312 317 |  | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -110,8 +110,10 @@ class ::Thread | |
| 110 110 | 
             
            end
         | 
| 111 111 |  | 
| 112 112 | 
             
            if RUBY_VERSION == '1.9.3'
         | 
| 113 | 
            +
              Thread.current[:name] = 'main'
         | 
| 114 | 
            +
             | 
| 113 115 | 
             
              trap('USR1') do
         | 
| 114 | 
            -
                threads = Thread.list.map { |th| { :inspect => th.inspect, :calback => th[:callback], :backtrace => th.backtrace } }
         | 
| 116 | 
            +
                threads = Thread.list.map { |th| { :inspect => th.inspect, :name => th[:name], :calback => th[:callback], :backtrace => th.backtrace } }
         | 
| 115 117 | 
             
                pp threads
         | 
| 116 118 | 
             
              end
         | 
| 117 119 | 
             
            end
         | 
    
        data/spec/support/logging.rb
    CHANGED
    
    | @@ -3,14 +3,13 @@ module ZK | |
| 3 3 |  | 
| 4 4 | 
             
              def self.logging_gem_setup
         | 
| 5 5 | 
             
                layout = ::Logging.layouts.pattern(
         | 
| 6 | 
            -
                  :pattern => '%.1l, [%d #%p] % | 
| 7 | 
            -
                  :date_pattern => '% | 
| 6 | 
            +
                  :pattern => '%.1l, [%d #%p] (%9.9T) %25.25c{2}:  %m\n',
         | 
| 7 | 
            +
                  :date_pattern => '%H:%M:%S.%6N'
         | 
| 8 8 | 
             
                )
         | 
| 9 9 |  | 
| 10 | 
            -
             | 
| 11 10 | 
             
                appender = ENV['ZK_DEBUG'] ? ::Logging.appenders.stderr : ::Logging.appenders.file(ZK::TEST_LOG_PATH)
         | 
| 12 11 | 
             
                appender.layout = layout
         | 
| 13 | 
            -
             | 
| 12 | 
            +
            #     appender.immediate_at = "debug,info,warn,error,fatal"
         | 
| 14 13 | 
             
            #     appender.auto_flushing = true
         | 
| 15 14 | 
             
                appender.auto_flushing = 25
         | 
| 16 15 | 
             
                appender.flush_period = 5
         | 
    
        metadata
    CHANGED