Class: ZK::Election::Observer

Inherits:
Base
  • Object
show all
Defined in:
lib/z_k/election.rb

Instance Attribute Summary

Attributes inherited from Base

#root_election_node, #vote_path, #zk

Instance Method Summary collapse

Methods inherited from Base

#cast_ballot!, #create_root_path!, #digit, #leader_ack_path, #leader_acked?, #leader_data, #on_leader_ack, #root_vote_path, #safe_call, #vote_basename

Constructor Details

#initialize(client, name, opts = {}) ⇒ Observer

Returns a new instance of Observer.



319
320
321
322
323
324
325
326
# File 'lib/z_k/election.rb', line 319

def initialize(client, name, opts={})
  super
  @leader_death_cbs = []
  @new_leader_cbs = []
  @deletion_sub = @creation_sub = nil
  @leader_alive = nil
  @observing = false
end

Instance Method Details

#closeObject



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/z_k/election.rb', line 377

def close
  @mutex.synchronize do
    return unless @observing

    @deletion_sub.unregister if @deletion_sub
    @creation_sub.unregister if @creation_sub

    @deletion_sub = @creation_sub = nil

    @leader_death_cbs.clear
    @new_leader_cbs.clear

    @leader_alive = nil
    @observing = false
  end
end

#leader_aliveObject

our current idea about the state of the election



329
330
331
# File 'lib/z_k/election.rb', line 329

def leader_alive #:nodoc:
  @mutex.synchronize { @leader_alive }
end

#long_live_the_kingObject (protected)



404
405
406
407
408
409
410
411
# File 'lib/z_k/election.rb', line 404

def long_live_the_king
  @mutex.synchronize do
    safe_call(*@new_leader_cbs)
    @leader_alive = true
  end

  the_king_is_dead unless leader_acked?(true)
end

#observe!Object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'lib/z_k/election.rb', line 344

def observe!
  @mutex.synchronize do
    return if @observing 
    @observing = true

    @leader_ack_sub ||= @zk.watcher.register(leader_ack_path) do |event|
      logger.debug { "leader_ack_callback, event.node_deleted? #{event.node_deleted?}, event.node_created? #{event.node_created?}" }

      if event.node_deleted?
        the_king_is_dead 
      elsif event.node_created?
        long_live_the_king
      else
        acked = leader_acked?(true) 


        # If the current state of the system is not what we think it should be
        # a transition has occurred and we should fire our callbacks
        if (acked and !@leader_alive)
          long_live_the_king 
        elsif (!acked and @leader_alive)
          the_king_is_dead
        else
          # things are how we think they should be, so just wait for the
          # watch to fire
        end
      end
    end

    leader_acked?(true) ? long_live_the_king : the_king_is_dead
  end
end

#on_leaders_death(&blk) ⇒ Object

register callbacks that should be fired when a leader dies



334
335
336
# File 'lib/z_k/election.rb', line 334

def on_leaders_death(&blk)
  @leader_death_cbs << blk
end

#on_new_leader(&blk) ⇒ Object

register callbacks for when the new leader has acknowledged their role returns a subscription object that can be used to cancel further events



340
341
342
# File 'lib/z_k/election.rb', line 340

def on_new_leader(&blk)
  @new_leader_cbs << blk
end

#the_king_is_deadObject (protected)



395
396
397
398
399
400
401
402
# File 'lib/z_k/election.rb', line 395

def the_king_is_dead
  @mutex.synchronize do
    safe_call(*@leader_death_cbs)
    @leader_alive = false
  end

  long_live_the_king if leader_acked?(true)
end