class Eye::Checker

Constants

TYPES

Attributes

check_count[RW]
options[RW]
pid[RW]
process[RW]
type[RW]
value[RW]
values[RW]

Public Class Methods

create(pid, options = {}, process = nil) click to toggle source
# File lib/eye/checker.rb, line 51
def self.create(pid, options = {}, process = nil)
  get_class(options[:type]).new(pid, options, process)
rescue Object => ex
  log_ex(ex)
  nil
end
get_class(type) click to toggle source
# File lib/eye/checker.rb, line 42
def self.get_class(type)
  klass = eval("Eye::Checker::#{TYPES[type]}") rescue nil
  raise "Unknown checker #{type}" unless klass
  if deps = klass.requires
    Array(deps).each { |d| require d }
  end
  klass
end
name_and_class(type) click to toggle source
# File lib/eye/checker.rb, line 32
def self.name_and_class(type)
  type = type.to_sym
  return { name: type, type: type } if TYPES[type]

  if type =~ %r[\A(.*?)_?[0-9]+\z]
    ctype = Regexp.last_match(1).to_sym
    return { name: type, type: ctype } if TYPES[ctype]
  end
end
new(pid, options = {}, process = nil) click to toggle source
# File lib/eye/checker.rb, line 62
def initialize(pid, options = {}, process = nil)
  @process = process
  @pid = pid
  @options = options.dup
  @type = options[:type]
  @full_name = @process.full_name if @process
  @initialized_at = Time.now

  debug { "create checker, with #{options}" }

  @value = nil
  @values = Eye::Utils::Tail.new(max_tries)
  @check_count = 0
end
register(base) click to toggle source
# File lib/eye/checker.rb, line 215
def self.register(base)
  name = base.to_s.gsub('Eye::Checker::', '')
  type = name.underscore.to_sym
  Eye::Checker::TYPES[type] = name
  Eye::Checker.const_set(name, base)
end
requires() click to toggle source
# File lib/eye/checker.rb, line 222
def self.requires; end
validate!(options) click to toggle source
# File lib/eye/checker.rb, line 58
def self.validate!(options)
  get_class(options[:type]).validate(options)
end

Public Instance Methods

check() click to toggle source
# File lib/eye/checker.rb, line 98
def check
  if initial_grace
    if Time.now - @initialized_at < initial_grace
      debug { 'skipped initial grace' }
      return true
    else
      @options[:initial_grace] = nil
    end
  end

  @value = get_value_safe
  @good_value = good?(value)
  @values << { value: @value, good: @good_value }

  result = true
  @check_count += 1

  if @values.size == max_tries
    bad_count = @values.count { |v| !v[:good] }
    result = false if bad_count >= min_tries
  end

  if skip_initial_fails
    if @good_value
      @options[:skip_initial_fails] = nil
    else
      result = true
    end
  end

  info { "#{last_human_values} => #{result ? 'OK' : 'Fail'}" }
  result
rescue Object => ex
  raise(ex) if ex.class == Celluloid::TaskTerminated
  log_ex(ex)
end
check_name() click to toggle source
# File lib/eye/checker.rb, line 153
def check_name
  @check_name ||= @type.to_s
end
defer(&block) click to toggle source
# File lib/eye/checker.rb, line 203
def defer(&block)
  Celluloid::Future.new(&block).value
end
fire() click to toggle source
# File lib/eye/checker.rb, line 189
def fire
  actions = fires ? Array(fires) : [:restart]
  process.notify :warn, "Bounded #{check_name}: #{last_human_values} send to #{actions}"

  actions.each do |action|
    reason = "bounded #{check_name}"
    if action.is_a?(Proc)
      process.schedule command: :instance_exec, reason: reason, block: action
    else
      process.schedule command: action, reason: reason
    end
  end
end
get_value() click to toggle source
# File lib/eye/checker.rb, line 139
def get_value
  raise NotImplementedError
end
get_value_safe() click to toggle source
# File lib/eye/checker.rb, line 135
def get_value_safe
  get_value
end
good?(value) click to toggle source

true if check ok false if check bad

# File lib/eye/checker.rb, line 149
def good?(value)
  value
end
human_value(value) click to toggle source
# File lib/eye/checker.rb, line 143
def human_value(value)
  value.to_s
end
inspect() click to toggle source
# File lib/eye/checker.rb, line 77
def inspect
  "<#{self.class} @process='#{@full_name}' @options=#{@options} @pid=#{@pid}>"
end
last_human_values() click to toggle source
# File lib/eye/checker.rb, line 89
def last_human_values
  h_values = @values.map do |v|
    sign = v[:good] ? '' : '*'
    sign + human_value(v[:value]).to_s
  end

  '[' + h_values * ', ' + ']'
end
logger_sub_tag() click to toggle source
# File lib/eye/checker.rb, line 85
def logger_sub_tag
  @logger_sub_tag ||= "check:#{check_name}"
end
logger_tag() click to toggle source
# File lib/eye/checker.rb, line 81
def logger_tag
  @logger_tag ||= @process ? @process.logger.prefix : nil
end
max_tries() click to toggle source
# File lib/eye/checker.rb, line 157
def max_tries
  @max_tries ||= if times
    if times.is_a?(Array)
      times[-1].to_i
    else
      times.to_i
    end
  else
    1
  end
end
min_tries() click to toggle source
# File lib/eye/checker.rb, line 169
def min_tries
  @min_tries ||= if times
    if times.is_a?(Array)
      times[0].to_i
    else
      max_tries
    end
  else
    max_tries
  end
end
previous_value() click to toggle source
# File lib/eye/checker.rb, line 181
def previous_value
  @values[-1][:value] if @values.present?
end
run_in_process_context(p) click to toggle source
# File lib/eye/checker.rb, line 185
def run_in_process_context(p)
  process.instance_exec(&p) if process.alive?
end