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, SslSocket

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', ssl_socket: 'SslSocket' }

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.



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

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.



24
25
26
# File 'lib/eye/checker.rb', line 24

def check_count
  @check_count
end

#optionsObject

Returns the value of attribute options.



24
25
26
# File 'lib/eye/checker.rb', line 24

def options
  @options
end

#pidObject

Returns the value of attribute pid.



24
25
26
# File 'lib/eye/checker.rb', line 24

def pid
  @pid
end

#processObject

Returns the value of attribute process.



24
25
26
# File 'lib/eye/checker.rb', line 24

def process
  @process
end

#typeObject

Returns the value of attribute type.



24
25
26
# File 'lib/eye/checker.rb', line 24

def type
  @type
end

#valueObject

Returns the value of attribute value.



24
25
26
# File 'lib/eye/checker.rb', line 24

def value
  @value
end

#valuesObject

Returns the value of attribute values.



24
25
26
# File 'lib/eye/checker.rb', line 24

def values
  @values
end

Class Method Details

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



51
52
53
54
55
56
57
# 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) ⇒ Object



42
43
44
45
46
47
48
49
# 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) ⇒ Object



32
33
34
35
36
37
38
39
40
# 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

.register(base) ⇒ Object



216
217
218
219
220
221
# File 'lib/eye/checker.rb', line 216

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



223
224
# File 'lib/eye/checker.rb', line 223

def self.requires
end

.validate!(options) ⇒ Object



59
60
61
# File 'lib/eye/checker.rb', line 59

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

Instance Method Details

#checkObject



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

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
  log_ex(ex)
end

#check_nameObject



154
155
156
# File 'lib/eye/checker.rb', line 154

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

#defer(&block) ⇒ Object



204
205
206
# File 'lib/eye/checker.rb', line 204

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

#fireObject



190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/eye/checker.rb', line 190

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

  actions.each do |action|
    reason = Eye::Reason.new("bounded #{check_name}")
    if action.is_a?(Proc)
      process.schedule :execute_proc, reason, &action
    else
      process.schedule action, reason
    end
  end
end

#get_valueObject

Raises:

  • (NotImplementedError)


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

def get_value
  raise NotImplementedError
end

#get_value_safeObject



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

def get_value_safe
  get_value
end

#good?(value) ⇒ Boolean

true if check ok false if check bad

Returns:

  • (Boolean)


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

def good?(value)
  value
end

#human_value(value) ⇒ Object



144
145
146
# File 'lib/eye/checker.rb', line 144

def human_value(value)
  value.to_s
end

#inspectObject



78
79
80
# File 'lib/eye/checker.rb', line 78

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

#last_human_valuesObject



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

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



86
87
88
# File 'lib/eye/checker.rb', line 86

def logger_sub_tag
  @logger_sub_tag ||= "check:#{check_name}"
end

#logger_tagObject



82
83
84
# File 'lib/eye/checker.rb', line 82

def logger_tag
  @logger_tag ||= @process ? @process.logger.prefix : nil
end

#max_triesObject



158
159
160
161
162
163
164
165
166
167
168
# File 'lib/eye/checker.rb', line 158

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



170
171
172
173
174
175
176
177
178
179
180
# File 'lib/eye/checker.rb', line 170

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



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

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

#run_in_process_context(p) ⇒ Object



186
187
188
# File 'lib/eye/checker.rb', line 186

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