Class: God::Watch

Inherits:
Task
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/god/watch.rb

Overview

The Watch class is a specialized Task that handles standard process workflows. It has four states: init, up, start, and restart.

Constant Summary collapse

VALID_STATES =

The Array of Symbol valid task states.

[:init, :up, :start, :restart]
INITIAL_STATE =

The Sybmol initial state.

:init
DEFAULT_KEEPALIVE_INTERVAL =

Default Integer interval at which keepalive will runn poll checks.

5.seconds
DEFAULT_KEEPALIVE_MEMORY_TIMES =

Default Integer or Array of Integers specification of how many times the memory condition must fail before triggering.

[3, 5]
DEFAULT_KEEPALIVE_CPU_TIMES =

Default Integer or Array of Integers specification of how many times the CPU condition must fail before triggering.

[3, 5]

Instance Attribute Summary collapse

Attributes inherited from Task

#autostart, #behaviors, #directory, #driver, #group, #initial_state, #interval, #metrics, #name, #state, #valid_states

Instance Method Summary collapse

Methods inherited from Task

#attach, #autostart?, #canonical_hash_form, #dest_desc, #detach, #handle_event, #handle_poll, #lifecycle, #log_line, #method_missing, #move, #notify, #prepare, #signal, #transition, #trigger, #trigger?, #unmonitor

Constructor Details

#initializeWatch

Initialize a new Watch instance.


38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/god/watch.rb', line 38

def initialize
  super

  # This God::Process instance holds information specific to the process.
  @process = God::Process.new

  # Valid states.
  self.valid_states = VALID_STATES
  self.initial_state = INITIAL_STATE

  # No grace period by default.
  self.grace = self.start_grace = self.stop_grace = self.restart_grace = 0
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class God::Task

Instance Attribute Details

#graceObject

Public: The grace period for this process (seconds).


15
16
17
# File 'lib/god/watch.rb', line 15

def grace
  @grace
end

#restart_graceObject

Public: The restart grace period (seconds).


24
25
26
# File 'lib/god/watch.rb', line 24

def restart_grace
  @restart_grace
end

#start_graceObject

Public: The start grace period (seconds).


18
19
20
# File 'lib/god/watch.rb', line 18

def start_grace
  @start_grace
end

#stop_graceObject

Public: The stop grace period (seconds).


21
22
23
# File 'lib/god/watch.rb', line 21

def stop_grace
  @stop_grace
end

Instance Method Details

#action(a, c = nil) ⇒ Object

Perform an action.

a - The Symbol action to perform. One of :start, :restart, :stop. c - The Condition.

Returns this Watch.


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/god/watch.rb', line 253

def action(a, c = nil)
  if !self.driver.in_driver_context?
    # Called from outside Driver. Send an async message to Driver.
    self.driver.message(:action, [a, c])
  else
    # Called from within Driver.
    case a
    when :start
      call_action(c, :start)
      sleep(self.start_grace + self.grace)
    when :restart
      if self.restart
        call_action(c, :restart)
      else
        action(:stop, c)
        action(:start, c)
      end
      sleep(self.restart_grace + self.grace)
    when :stop
      call_action(c, :stop)
      sleep(self.stop_grace + self.grace)
    end
  end

  self
end

#behavior(kind) {|b| ... } ⇒ Object

Public: Add a behavior to this Watch. See lib/god/behavior.rb.

kind - The Symbol name of the Behavior to add.

Yields the newly instantiated Behavior.

Returns nothing.

Yields:

  • (b)

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/god/watch.rb', line 72

def behavior(kind)
  # Create the behavior.
  begin
    b = Behavior.generate(kind, self)
  rescue NoSuchBehaviorError => e
    abort e.message
  end

  # Send to block so config can set attributes.
  yield(b) if block_given?

  # Abort if the Behavior is invalid, the Behavior will have printed
  # out its own error messages by now.
  abort unless b.valid?

  self.behaviors << b
end

#call_action(condition, action) ⇒ Object

Perform the specifics of the action.

condition - The Condition. action - The Symbol action.

Returns nothing.


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/god/watch.rb', line 286

def call_action(condition, action)
  # Before.
  before_items = self.behaviors
  before_items += [condition] if condition
  before_items.each do |b|
    info = b.send("before_#{action}")
    if info
      msg = "#{self.name} before_#{action}: #{info} (#{b.base_name})"
      applog(self, :info, msg)
    end
  end

  # Log.
  if self.send(action)
    msg = "#{self.name} #{action}: #{self.send(action).to_s}"
    applog(self, :info, msg)
  end

  # Execute.
  @process.call_action(action)

  # After.
  after_items = self.behaviors
  after_items += [condition] if condition
  after_items.each do |b|
    info = b.send("after_#{action}")
    if info
      msg = "#{self.name} after_#{action}: #{info} (#{b.base_name})"
      applog(self, :info, msg)
    end
  end
end

#keepalive(options = {}) ⇒ Object

Public: A set of conditions for easily getting started with simple watch scenarios. Keepalive is intended for use by beginners or on processes that do not need very sophisticated monitoring.

If events are enabled, it will use the :process_exit event to determine if a process fails. Otherwise it will use the :process_running poll.

options - The option Hash. Possible values are:

:interval -     The Integer number of seconds on which to poll
                for process status. Affects CPU, memory, and
                :process_running conditions (if used).
                Default: 5.seconds.
:memory_max   - The Integer memory max. A bare integer means
                kilobytes. You may use Numeric.kilobytes,
                Numeric#megabytes, and Numeric#gigabytes to
                makes things more clear.
:memory_times - If :memory_max is set, :memory_times can be
                set to either an Integer or a 2 element
                Integer Array to specify the number of times
                the memory condition must fail. Examples:
                3 (three times), [3, 5] (three out of any five
                checks). Default: [3, 5].
:cpu_max      - The Integer CPU percentage max. Range is
                0 to 100. You may use the Numberic#percent
                sugar to clarify e.g. 50.percent.
:cpu_times    - If :cpu_max is set, :cpu_times can be
                set to either an Integer or a 2 element
                Integer Array to specify the number of times
                the memory condition must fail. Examples:
                3 (three times), [3, 5] (three out of any five
                checks). Default: [3, 5].

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/god/watch.rb', line 138

def keepalive(options = {})
  if God::EventHandler.loaded?
    self.transition(:init, { true => :up, false => :start }) do |on|
      on.condition(:process_running) do |c|
        c.interval = options[:interval] || DEFAULT_KEEPALIVE_INTERVAL
        c.running = true
      end
    end

    self.transition([:start, :restart], :up) do |on|
      on.condition(:process_running) do |c|
        c.interval = options[:interval] || DEFAULT_KEEPALIVE_INTERVAL
        c.running = true
      end
    end

    self.transition(:up, :start) do |on|
      on.condition(:process_exits)
    end
  else
    self.start_if do |start|
      start.condition(:process_running) do |c|
        c.interval = options[:interval] || DEFAULT_KEEPALIVE_INTERVAL
        c.running = false
      end
    end
  end

  self.restart_if do |restart|
    if options[:memory_max]
      restart.condition(:memory_usage) do |c|
        c.interval = options[:interval] || DEFAULT_KEEPALIVE_INTERVAL
        c.above = options[:memory_max]
        c.times = options[:memory_times] || DEFAULT_KEEPALIVE_MEMORY_TIMES
      end
    end

    if options[:cpu_max]
      restart.condition(:cpu_usage) do |c|
        c.interval = options[:interval] || DEFAULT_KEEPALIVE_INTERVAL
        c.above = options[:cpu_max]
        c.times = options[:cpu_times] || DEFAULT_KEEPALIVE_CPU_TIMES
      end
    end
  end
end

#monitorObject

Enable monitoring. Start at the first available of the init or up states.

Returns nothing.


233
234
235
236
237
238
239
# File 'lib/god/watch.rb', line 233

def monitor
  if !self.metrics[:init].empty?
    self.move(:init)
  else
    self.move(:up)
  end
end

#register!Object

Register the Process in the global process registry.

Returns nothing.


328
329
330
# File 'lib/god/watch.rb', line 328

def register!
  God.registry.add(@process)
end

#restart_ifObject

Public: Restart the process if any of the given conditions are triggered.

Yields the Metric upon which conditions can be added.

Returns nothing.


207
208
209
210
211
# File 'lib/god/watch.rb', line 207

def restart_if
  self.transition(:up, :restart) do |on|
    yield(on)
  end
end

#start_ifObject

Public: Start the process if any of the given conditions are triggered.

Yields the Metric upon which conditions can be added.

Returns nothing.


196
197
198
199
200
# File 'lib/god/watch.rb', line 196

def start_if
  self.transition(:up, :start) do |on|
    yield(on)
  end
end

#stop_ifObject

Public: Stop the process if any of the given conditions are triggered.

Yields the Metric upon which conditions can be added.

Returns nothing.


218
219
220
221
222
# File 'lib/god/watch.rb', line 218

def stop_if
  self.transition(:up, :stop) do |on|
    yield(on)
  end
end

#unregister!Object

Unregister the Process in the global process registry.

Returns nothing.


335
336
337
338
# File 'lib/god/watch.rb', line 335

def unregister!
  God.registry.remove(@process)
  super
end

#valid?Boolean

Is this Watch valid?

Returns true if the Watch is valid, false if not.

Returns:

  • (Boolean)

55
56
57
# File 'lib/god/watch.rb', line 55

def valid?
  super && @process.valid?
end