Class: Eye::Checker

Inherits:
Object show all
Includes:
Dsl::Validation
Defined in:
lib/eye/checker.rb

Direct Known Subclasses

CustomCell, Defer, FileCTime, FileTouched, Measure, Nop

Defined Under Namespace

Classes: ChildrenCount, ChildrenMemory, Cpu, Cputime, Custom, CustomCell, CustomDefer, Defer, FileCTime, FileSize, FileTouched, Http, Measure, Memory, Nop, Runtime, Socket

Constant Summary collapse

TYPES =
{:memory => 'Memory', :cpu => 'Cpu', :http => 'Http',
:ctime => 'FileCTime', :fsize => 'FileSize', :file_touched => 'FileTouched',
:socket => 'Socket', :nop => 'Nop', :runtime => 'Runtime', :cputime => 'Cputime',
:children_count => "ChildrenCount", :children_memory => "ChildrenMemory" }

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Dsl::Validation

included

Constructor Details

#initialize(pid, options = {}, process = nil) ⇒ Checker

Returns a new instance of Checker.


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

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

Instance Attribute Details

#check_countObject

Returns the value of attribute check_count


22
23
24
# File 'lib/eye/checker.rb', line 22

def check_count
  @check_count
end

#optionsObject

Returns the value of attribute options


22
23
24
# File 'lib/eye/checker.rb', line 22

def options
  @options
end

#pidObject

Returns the value of attribute pid


22
23
24
# File 'lib/eye/checker.rb', line 22

def pid
  @pid
end

#processObject

Returns the value of attribute process


22
23
24
# File 'lib/eye/checker.rb', line 22

def process
  @process
end

#typeObject

Returns the value of attribute type


22
23
24
# File 'lib/eye/checker.rb', line 22

def type
  @type
end

#valueObject

Returns the value of attribute value


22
23
24
# File 'lib/eye/checker.rb', line 22

def value
  @value
end

#valuesObject

Returns the value of attribute values


22
23
24
# File 'lib/eye/checker.rb', line 22

def values
  @values
end

Class Method Details

.create(pid, options = {}, process = nil) ⇒ Object


49
50
51
52
53
54
55
# File 'lib/eye/checker.rb', line 49

def self.create(pid, options = {}, process = nil)
  get_class(options[:type]).new(pid, options, process)

rescue Exception, Timeout::Error => ex
  log_ex(ex)
  nil
end

.get_class(type) ⇒ Object


40
41
42
43
44
45
46
47
# File 'lib/eye/checker.rb', line 40

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) ⇒ Object


30
31
32
33
34
35
36
37
38
# File 'lib/eye/checker.rb', line 30

def self.name_and_class(type)
  type = type.to_sym
  return {:name => type, :type => type} if TYPES[type]

  if type =~ /\A(.*?)_?[0-9]+\z/
    ctype = $1.to_sym
    return {:name => type, :type => ctype} if TYPES[ctype]
  end
end

.register(base) ⇒ Object


205
206
207
208
209
210
# File 'lib/eye/checker.rb', line 205

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

.requiresObject


212
213
# File 'lib/eye/checker.rb', line 212

def self.requires
end

.validate!(options) ⇒ Object


57
58
59
# File 'lib/eye/checker.rb', line 57

def self.validate!(options)
  get_class(options[:type]).validate(options)
end

Instance Method Details

#checkObject


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
# File 'lib/eye/checker.rb', line 97

def check
  if initial_grace && (Time.now - @initialized_at < initial_grace)
    debug { 'skipped initial grace' }
    return true
  else
    @options[:initial_grace] = nil
  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 Exception, Timeout::Error => ex
  log_ex(ex)
end

#check_nameObject


150
151
152
# File 'lib/eye/checker.rb', line 150

def check_name
  @check_name ||= @type.to_s
end

#defer(&block) ⇒ Object


195
196
197
# File 'lib/eye/checker.rb', line 195

def defer(&block)
  Celluloid::Future.new(&block).value
end

#fireObject


186
187
188
189
190
191
192
193
# File 'lib/eye/checker.rb', line 186

def fire
  actions = fires ? Array(fires) : [:restart]
  process.notify :warn, "Bounded #{check_name}: #{last_human_values} send to #{actions}"

  actions.each do |action|
    process.schedule action, Eye::Reason.new("bounded #{check_name}")
  end
end

#get_valueObject

Raises:

  • (NotImplementedError)

136
137
138
# File 'lib/eye/checker.rb', line 136

def get_value
  raise NotImplementedError
end

#get_value_safeObject


132
133
134
# File 'lib/eye/checker.rb', line 132

def get_value_safe
  get_value
end

#good?(value) ⇒ Boolean

true if check ok false if check bad

Returns:

  • (Boolean)

146
147
148
# File 'lib/eye/checker.rb', line 146

def good?(value)
  value
end

#human_value(value) ⇒ Object


140
141
142
# File 'lib/eye/checker.rb', line 140

def human_value(value)
  value.to_s
end

#inspectObject


76
77
78
# File 'lib/eye/checker.rb', line 76

def inspect
  "<#{self.class} @process='#{@full_name}' @options=#{@options} @pid=#{@pid}>"
end

#last_human_valuesObject


88
89
90
91
92
93
94
95
# File 'lib/eye/checker.rb', line 88

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_tagObject


84
85
86
# File 'lib/eye/checker.rb', line 84

def logger_sub_tag
  "check:#{check_name}"
end

#logger_tagObject


80
81
82
# File 'lib/eye/checker.rb', line 80

def logger_tag
  @process.logger.prefix if @process
end

#max_triesObject


154
155
156
157
158
159
160
161
162
163
164
# File 'lib/eye/checker.rb', line 154

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_triesObject


166
167
168
169
170
171
172
173
174
175
176
# File 'lib/eye/checker.rb', line 166

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_valueObject


178
179
180
# File 'lib/eye/checker.rb', line 178

def previous_value
  @values[-1][:value] if @values.present?
end

#run_in_process_context(p) ⇒ Object


182
183
184
# File 'lib/eye/checker.rb', line 182

def run_in_process_context(p)
  process.instance_exec(&p) if process.alive?
end