Class: God::Watch

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

Constant Summary collapse

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeWatch



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/god/watch.rb', line 29

def initialize
  @autostart ||= true
  @process = God::Process.new
        
  # no grace period by default
  self.grace = self.start_grace = self.stop_grace = self.restart_grace = 0
  
  # the list of behaviors
  self.behaviors = []
  
  # the list of conditions for each action
  self.metrics = {:init => [],
                  :start => [],
                  :restart => [],
                  :up => []}
                     
  # mutex
  self.mutex = Mutex.new
end

Instance Attribute Details

#autostart=(value) ⇒ Object (writeonly)

Sets the attribute autostart



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

def autostart=(value)
  @autostart = value
end

#behaviorsObject

api



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

def behaviors
  @behaviors
end

#graceObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def grace
  @grace
end

#groupObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def group
  @group
end

#intervalObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def interval
  @interval
end

#metricsObject

api



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

def metrics
  @metrics
end

#mutexObject

internal



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

def mutex
  @mutex
end

#restart_graceObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def restart_grace
  @restart_grace
end

#start_graceObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def start_grace
  @start_grace
end

#stateObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def state
  @state
end

#stop_graceObject

config



10
11
12
# File 'lib/god/watch.rb', line 10

def stop_grace
  @stop_grace
end

Instance Method Details

#action(a, c = nil) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/god/watch.rb', line 167

def action(a, c = nil)
  case a
  when :start
    Syslog.debug(self.start.to_s)
    puts self.start.to_s
    call_action(c, :start)
    sleep(self.start_grace + self.grace)
  when :restart
    if self.restart
      Syslog.debug(self.restart.to_s)
      puts self.restart
      call_action(c, :restart)
    else
      action(:stop, c)
      action(:start, c)
    end
    sleep(self.restart_grace + self.grace)
  when :stop
    Syslog.debug(self.stop.to_s)
    puts self.stop.to_s
    call_action(c, :stop)
    sleep(self.stop_grace + self.grace)
  end      
end

#autostart?Boolean



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

def autostart?; @autostart; end

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

Yields:

  • (b)


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/god/watch.rb', line 49

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



192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/god/watch.rb', line 192

def call_action(condition, action)
  # before
  before_items = self.behaviors
  before_items += [condition] if condition
  before_items.each { |b| b.send("before_#{action}") }
  
  @process.call_action(action)

  # after
  after_items = self.behaviors
  after_items += [condition] if condition
  after_items.each { |b| b.send("after_#{action}") }
end

#canonical_hash_form(to) ⇒ Object



206
207
208
# File 'lib/god/watch.rb', line 206

def canonical_hash_form(to)
  to.instance_of?(Symbol) ? {true => to} : to
end

#monitorObject

Enable monitoring



121
122
123
124
125
126
127
128
# File 'lib/god/watch.rb', line 121

def monitor
  # start monitoring at the first available of the init or up states
  if !self.metrics[:init].empty?
    self.move(:init)
  else
    self.move(:up)
  end
end

#move(to_state) ⇒ Object

Move from one state to another



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

def move(to_state)
  msg = "#{self.name} move '#{self.state}' to '#{to_state}'"
  Syslog.debug(msg)
  puts msg
   
  # cleanup from current state
  from_state = self.state
  if from_state
    self.metrics[from_state].each { |m| m.disable }
  end
  
  # perform action
  self.action(to_state)
  
  # enable simple mode
  if [:start, :restart].include?(to_state) && self.metrics[to_state].empty?
    to_state = :up
  end
  
  # move to new state
  if to_state
    self.metrics[to_state].each { |m| m.enable }
  end
  
  # set state
  self.state = to_state
  
  # return self
  self
end

#register!Object



210
211
212
# File 'lib/god/watch.rb', line 210

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

#restart_ifObject



108
109
110
111
112
# File 'lib/god/watch.rb', line 108

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

#start_ifObject

Simple mode



102
103
104
105
106
# File 'lib/god/watch.rb', line 102

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

#transition(start_states, end_states) ⇒ Object

Define a transition handler which consists of a set of conditions



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

def transition(start_states, end_states)
  # convert to into canonical hash form
  canonical_end_states = canonical_hash_form(end_states)
  
  # for each start state do
  Array(start_states).each do |start_state|
    # validate start state
    unless VALID_STATES.include?(start_state)
      abort "Invalid state :#{start_state}. Must be one of the symbols #{VALID_STATES.map{|x| ":#{x}"}.join(', ')}"
    end
    
    # create a new metric to hold the watch, end states, and conditions
    m = Metric.new(self, canonical_end_states)
    
    # let the config file define some conditions on the metric
    yield(m)
    
    # record the metric
    self.metrics[start_state] << m
  end
end

#unmonitorObject

Disable monitoring



131
132
133
# File 'lib/god/watch.rb', line 131

def unmonitor
  self.move(nil)
end