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].freeze
INITIAL_STATE =

The Symbol initial state.

:init
DEFAULT_KEEPALIVE_INTERVAL =

Default Integer interval at which keepalive will run 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].freeze
DEFAULT_KEEPALIVE_CPU_TIMES =

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

[3, 5].freeze

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.



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

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).



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

def grace
  @grace
end

#restart_graceObject

Public: The restart grace period (seconds).



26
27
28
# File 'lib/god/watch.rb', line 26

def restart_grace
  @restart_grace
end

#start_graceObject

Public: The start grace period (seconds).



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

def start_grace
  @start_grace
end

#stop_graceObject

Public: The stop grace period (seconds).



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

def stop_grace
  @stop_grace
end

Instance Method Details

#action(action, condition = nil) ⇒ Object

Perform an action.

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

Returns this Watch.



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

def action(action, condition = nil)
  if driver.in_driver_context?
    # Called from within Driver.
    case action
    when :start
      call_action(condition, :start)
      sleep(start_grace + grace)
    when :restart
      if restart
        call_action(condition, :restart)
      else
        action(:stop, condition)
        action(:start, condition)
      end
      sleep(restart_grace + grace)
    when :stop
      call_action(condition, :stop)
      sleep(stop_grace + grace)
    end
  else
    # Called from outside Driver. Send an async message to Driver.
    driver.message(:action, [action, condition])
  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)


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

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?

  behaviors << b
end

#call_action(condition, action) ⇒ Object

Perform the specifics of the action.

condition - The Condition. action - The Symbol action.

Returns nothing.



282
283
284
285
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
# File 'lib/god/watch.rb', line 282

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

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

  # Execute.
  @process.call_action(action)

  # After.
  after_items = behaviors
  after_items += [condition] if condition
  after_items.each do |b|
    info = b.send(:"after_#{action}")
    if info
      msg = "#{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 Numeric#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].


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
184
185
# File 'lib/god/watch.rb', line 140

def keepalive(options = {})
  if God::EventHandler.loaded?
    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

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

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

  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.



229
230
231
232
233
234
235
# File 'lib/god/watch.rb', line 229

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

#register!Object

Register the Process in the global process registry.

Returns nothing.



324
325
326
# File 'lib/god/watch.rb', line 324

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

#restart_if(&block) ⇒ Object

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
# File 'lib/god/watch.rb', line 207

def restart_if(&block)
  transition(:up, :restart, &block)
end

#start_if(&block) ⇒ Object

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

Yields the Metric upon which conditions can be added.

Returns nothing.



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

def start_if(&block)
  transition(:up, :start, &block)
end

#stop_if(&block) ⇒ Object

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

Yields the Metric upon which conditions can be added.

Returns nothing.



216
217
218
# File 'lib/god/watch.rb', line 216

def stop_if(&block)
  transition(:up, :stop, &block)
end

#unregister!Object

Unregister the Process in the global process registry.

Returns nothing.



331
332
333
334
# File 'lib/god/watch.rb', line 331

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)


57
58
59
# File 'lib/god/watch.rb', line 57

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