module RedisFailover # Represents a snapshot of a particular redis node as seen by all currently running # redis node managers. class NodeSnapshot # @return [String] the redis node attr_reader :node # Creates a new instance. # # @param [String] the redis node # @see NodeManager#initialize def initialize(node) @node = node @available = {} @unavailable = [] end # Declares this node available by the specified node manager. # # @param [String] node_manager the node manager id # @param [Integer] latency the latency def viewable_by(node_manager, latency) @available[node_manager] = latency end # Determines if this node is viewable by a node manager. # # @param [String] node_manager the node manager id def viewable_by?(node_manager) @available.key?(node_manager) end # Declares this node unavailable by the specified node manager. # # @param [String] node_manager the node manager id def unviewable_by(node_manager) @unavailable << node_manager end # @return [Integer] the number of node managers saying # this node is available def available_count @available.size end # @return [Integer] the number of node managers saying # this node is unavailable def unavailable_count @unavailable.size end # @return [Integer] the average available latency def avg_latency return if @available.empty? @available.values.inject(0) { |sum, n| sum + n } / @available.size end # @return [Array] all node managers involved in this snapshot def node_managers (@available.keys + @unavailable).uniq end # @return [Boolean] true if all node managers indicated that this # node was viewable def all_available? available_count > 0 && unavailable_count == 0 end # @return [Boolean] true if all node managers indicated that this # node was unviewable def all_unavailable? unavailable_count > 0 && available_count == 0 end # @return [String] a friendly representation of this node snapshot def to_s 'Node %s available by %p, unavailable by %p (%d up, %d down)' % [node, @available, @unavailable, available_count, unavailable_count] end end end