Class: RightScale::ConnectivityChecker

Inherits:
Object
  • Object
show all
Defined in:
lib/right_agent/connectivity_checker.rb

Overview

Broker connectivity checker Checks connectivity when requested

Constant Summary collapse

MIN_RESTART_INACTIVITY_TIMER_INTERVAL =

Minimum number of seconds between restarts of the inactivity timer

60
PING_TIMEOUT =

Number of seconds to wait for ping response from a RightNet router when checking connectivity

30
MAX_PING_TIMEOUTS =

Default maximum number of consecutive ping timeouts before attempt to reconnect

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sender, check_interval, ping_stats) ⇒ ConnectivityChecker

Returns a new instance of ConnectivityChecker.



41
42
43
44
45
46
47
48
49
50
# File 'lib/right_agent/connectivity_checker.rb', line 41

def initialize(sender, check_interval, ping_stats)
  @sender = sender
  @check_interval = check_interval
  @ping_timeouts = {}
  @ping_timer = nil
  @ping_stats = ping_stats
  @last_received = Time.now
  @message_received_callbacks = []
  restart_inactivity_timer if @check_interval > 0
end

Instance Attribute Details

#ping_timerObject

Timer while waiting for RightNet router ping response



39
40
41
# File 'lib/right_agent/connectivity_checker.rb', line 39

def ping_timer
  @ping_timer
end

Instance Method Details

#check(id = nil, max_ping_timeouts = MAX_PING_TIMEOUTS) ⇒ Object

Check whether broker connection is usable by pinging a router via that broker Attempt to reconnect if ping does not respond in PING_TIMEOUT seconds and if have reached timeout limit Ignore request if already checking a connection

Parameters

id(String)

Identity of specific broker to use to send ping, defaults to any

currently connected broker
max_ping_timeouts(Integer)

Maximum number of ping timeouts before attempt

to reconnect, defaults to MAX_PING_TIMEOUTS

Return

true

Always return true



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/right_agent/connectivity_checker.rb', line 90

def check(id = nil, max_ping_timeouts = MAX_PING_TIMEOUTS)
  unless @terminating || @ping_timer || (id && !@sender.agent.client.connected?(id))
    @ping_id = id
    @ping_timer = EM::Timer.new(PING_TIMEOUT) do
      if @ping_id
        begin
          @ping_stats.update("timeout")
          @ping_timer = nil
          @ping_timeouts[@ping_id] = (@ping_timeouts[@ping_id] || 0) + 1
          if @ping_timeouts[@ping_id] >= max_ping_timeouts
            ErrorTracker.log(self, "Mapper ping via broker #{@ping_id} timed out after #{PING_TIMEOUT} seconds and now " +
                                   "reached maximum of #{max_ping_timeouts} timeout#{max_ping_timeouts > 1 ? 's' : ''}, " +
                                   "attempting to reconnect")
            host, port, index, priority = @sender.client.identity_parts(@ping_id)
            @sender.agent.connect(host, port, index, priority, force = true)
          else
            Log.warning("Mapper ping via broker #{@ping_id} timed out after #{PING_TIMEOUT} seconds")
          end
        rescue Exception => e
          ErrorTracker.log(self, "Failed to reconnect to broker #{@ping_id}", e)
        end
      else
        @ping_timer = nil
      end
    end

    handler = lambda do |_|
      begin
        if @ping_timer
          @ping_stats.update("success")
          @ping_timer.cancel
          @ping_timer = nil
          @ping_timeouts[@ping_id] = 0
          @ping_id = nil
        end
      rescue Exception => e
        ErrorTracker.log(self, "Failed to cancel router ping", e)
      end
    end
    request = Request.new("/router/ping", nil, {:from => @sender.identity, :token => AgentIdentity.generate})
    @sender.pending_requests[request.token] = PendingRequest.new(Request, Time.now, handler)
    ids = [@ping_id] if @ping_id
    @ping_id = @sender.send(:publish, request, ids).first
  end
  true
end

#message_received(&callback) ⇒ Object

Update the time this agent last received a request or response message and restart the inactivity timer thus deferring the next connectivity check Also forward this message receipt notification to any callbacks that have registered

Block

Optional block without parameters that is activated when a message is received

Return

true

Always return true



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/right_agent/connectivity_checker.rb', line 61

def message_received(&callback)
  if block_given?
    @message_received_callbacks << callback
  else
    @message_received_callbacks.each { |c| c.call }
    if @check_interval > 0
      now = Time.now
      if (now - @last_received) > MIN_RESTART_INACTIVITY_TIMER_INTERVAL
        @last_received = now
        restart_inactivity_timer
      end
    end
  end
  true
end

#terminateObject

Prepare for agent termination

Return

true

Always return true



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/right_agent/connectivity_checker.rb', line 141

def terminate
  @terminating = true
  @check_interval = 0
  if @ping_timer
    @ping_timer.cancel
    @ping_timer = nil
  end
  if @inactivity_timer
    @inactivity_timer.cancel
    @inactivity_timer = nil
  end
  true
end