From 5ec4c3a5b269d0d887fe01aa764b83497334ddf4 Mon Sep 17 00:00:00 2001 From: Tom Preston-Werner Date: Mon, 18 Jun 2007 23:07:30 -0700 Subject: [PATCH] extracted behavior code --- lib/god.rb | 4 ++- lib/god/{condition.rb => behavior.rb} | 22 ++------------- lib/god/behaviors/clean_pid_file.rb | 23 +++++++++++++++ lib/god/condition.rb | 47 ++----------------------------- lib/god/conditions/cpu_usage.rb | 12 ++++---- lib/god/conditions/memory_usage.rb | 12 ++++---- lib/god/conditions/process_not_running.rb | 13 +++++++-- lib/god/errors.rb | 3 ++ lib/god/process_condition.rb | 30 -------------------- lib/god/watch.rb | 25 +++++++++++++++- test/configs/real.rb | 6 +++- test/helper.rb | 5 +++- test/test_behavior.rb | 9 ++++++ test/test_watch.rb | 9 ++++++ 14 files changed, 110 insertions(+), 110 deletions(-) copy lib/god/{condition.rb => behavior.rb} (60%) create mode 100644 lib/god/behaviors/clean_pid_file.rb delete mode 100644 lib/god/process_condition.rb create mode 100644 test/test_behavior.rb diff --git a/lib/god.rb b/lib/god.rb index 8097e25..61abc13 100644 --- a/lib/god.rb +++ b/lib/god.rb @@ -6,8 +6,10 @@ require 'god/errors' require 'god/system/process' +require 'god/behavior' +require 'god/behaviors/clean_pid_file' + require 'god/condition' -require 'god/process_condition' require 'god/conditions/timeline' require 'god/conditions/process_not_running' require 'god/conditions/memory_usage' diff --git a/lib/god/condition.rb b/lib/god/behavior.rb similarity index 60% copy from lib/god/condition.rb copy to lib/god/behavior.rb index 0f68ba9..ddc18dd 100644 --- a/lib/god/condition.rb +++ b/lib/god/behavior.rb @@ -1,11 +1,11 @@ module God - class Condition < Base + class Behavior < Base def self.generate(kind) sym = kind.to_s.capitalize.gsub(/_(.)/){$1.upcase}.intern - God::Conditions.const_get(sym).new + God::Behaviors.const_get(sym).new rescue NameError - raise NoSuchConditionError.new("No Condition found with the class name God::Conditions::#{sym}") + raise NoSuchBehaviorError.new("No Behavior found with the class name God::Behaviors::#{sym}") end # Override this method in your Conditions (optional) @@ -24,22 +24,6 @@ module God true end - # Override this method in your Conditions (optional) - def before - end - - # Override this method in your Conditions (mandatory) - # - # Return true if the test passes (everything is ok) - # Return false otherwise - def test - raise AbstractMethodNotOverriddenError.new("Condition#test must be overridden in subclasses") - end - - # Override this method in your Conditions (optional) - def after - end - ####### def before_start diff --git a/lib/god/behaviors/clean_pid_file.rb b/lib/god/behaviors/clean_pid_file.rb new file mode 100644 index 0000000..5e889cb --- /dev/null +++ b/lib/god/behaviors/clean_pid_file.rb @@ -0,0 +1,23 @@ +module God + module Behaviors + + class CleanPidFile < Behavior + attr_accessor :pid_file + + def initialize + self.pid_file = nil + end + + def valid? + valid = true + valid &= complain("You must specify the 'pid_file' attribute for :clean_pid_file") if self.pid_file.nil? + valid + end + + def before_start + File.delete(self.pid_file) rescue nil + end + end + + end +end \ No newline at end of file diff --git a/lib/god/condition.rb b/lib/god/condition.rb index 0f68ba9..333b316 100644 --- a/lib/god/condition.rb +++ b/lib/god/condition.rb @@ -1,29 +1,13 @@ module God - class Condition < Base + class Condition < Behavior def self.generate(kind) sym = kind.to_s.capitalize.gsub(/_(.)/){$1.upcase}.intern God::Conditions.const_get(sym).new rescue NameError raise NoSuchConditionError.new("No Condition found with the class name God::Conditions::#{sym}") end - - # Override this method in your Conditions (optional) - # - # Called once after the Condition has been sent to the block and attributes have been - # set. Do any post-processing on attributes here - def prepare - - end - - # Override this method in your Conditions (optional) - # - # Called once during evaluation of the config file. - # If invalid attributes are found, use #complain('text') to print out the error message - def valid? - true - end - + # Override this method in your Conditions (optional) def before end @@ -39,33 +23,6 @@ module God # Override this method in your Conditions (optional) def after end - - ####### - - def before_start - end - - def after_start - end - - def before_restart - end - - def after_restart - end - - def before_stop - end - - def after_stop - end - - protected - - def complain(text) - puts text - false - end end end \ No newline at end of file diff --git a/lib/god/conditions/cpu_usage.rb b/lib/god/conditions/cpu_usage.rb index d5a10ec..e0f1e54 100644 --- a/lib/god/conditions/cpu_usage.rb +++ b/lib/god/conditions/cpu_usage.rb @@ -1,8 +1,8 @@ module God module Conditions - class CpuUsage < ProcessCondition - attr_accessor :above, :times + class CpuUsage < Condition + attr_accessor :pid_file, :above, :times def initialize super @@ -19,13 +19,15 @@ module God end def valid? - valid = super - valid = complain("You must specify the 'above' attribute for :memory_usage") if self.above.nil? + valid = true + valid &= complain("You must specify the 'pid_file' attribute for :memory_usage") if self.pid_file.nil? + valid &= complain("You must specify the 'above' attribute for :memory_usage") if self.above.nil? valid end def test - return false unless super + return false unless File.exist?(self.pid_file) + pid = File.open(self.pid_file).read.strip process = System::Process.new(pid) @timeline.push(process.percent_cpu) diff --git a/lib/god/conditions/memory_usage.rb b/lib/god/conditions/memory_usage.rb index c1515b4..269f1c5 100644 --- a/lib/god/conditions/memory_usage.rb +++ b/lib/god/conditions/memory_usage.rb @@ -1,8 +1,8 @@ module God module Conditions - class MemoryUsage < ProcessCondition - attr_accessor :above, :times + class MemoryUsage < Condition + attr_accessor :pid_file, :above, :times def initialize super @@ -19,13 +19,15 @@ module God end def valid? - valid = super - valid = complain("You must specify the 'above' attribute for :memory_usage") if self.above.nil? + valid = true + valid &= complain("You must specify the 'pid_file' attribute for :memory_usage") if self.pid_file.nil? + valid &= complain("You must specify the 'above' attribute for :memory_usage") if self.above.nil? valid end def test - return false unless super + return false unless File.exist?(self.pid_file) + pid = File.open(self.pid_file).read.strip process = System::Process.new(pid) @timeline.push(process.memory) diff --git a/lib/god/conditions/process_not_running.rb b/lib/god/conditions/process_not_running.rb index f9cb1d8..7e5bdfd 100644 --- a/lib/god/conditions/process_not_running.rb +++ b/lib/god/conditions/process_not_running.rb @@ -1,9 +1,18 @@ module God module Conditions - class ProcessNotRunning < ProcessCondition + class ProcessNotRunning < Condition + attr_accessor :pid_file + + def valid? + valid = true + valid &= complain("You must specify the 'pid_file' attribute for :process_not_running") if self.pid_file.nil? + valid + end + def test - return false unless super + return false unless File.exist?(self.pid_file) + pid = File.open(self.pid_file).read.strip process_running?(pid) end diff --git a/lib/god/errors.rb b/lib/god/errors.rb index 4d69de3..58ea9b1 100644 --- a/lib/god/errors.rb +++ b/lib/god/errors.rb @@ -6,4 +6,7 @@ module God class NoSuchConditionError < StandardError end + class NoSuchBehaviorError < StandardError + end + end \ No newline at end of file diff --git a/lib/god/process_condition.rb b/lib/god/process_condition.rb deleted file mode 100644 index 5b6a533..0000000 --- a/lib/god/process_condition.rb +++ /dev/null @@ -1,30 +0,0 @@ -module God - - # This abstract class makes it easy for subclassed Conditions to deal - # with commong process related tasks, like pid file cleanup - class ProcessCondition < Condition - attr_accessor :pid_file, :clean - - def initialize - self.pid_file = nil - self.clean = true - end - - def valid? - valid = true - valid = complain("You must specify the 'pid_file' attribute for :process_not_running") if self.pid_file.nil? - valid - end - - def test - File.exist?(self.pid_file) - end - - def before_start - if self.clean - File.delete(self.pid_file) rescue nil - end - end - end - -end \ No newline at end of file diff --git a/lib/god/watch.rb b/lib/god/watch.rb index 89c4b09..6f57947 100644 --- a/lib/god/watch.rb +++ b/lib/god/watch.rb @@ -5,7 +5,7 @@ module God attr_accessor :name, :cwd, :start, :stop, :restart, :grace # api - attr_accessor :conditions + attr_accessor :behaviors, :conditions # def initialize @@ -15,11 +15,34 @@ module God # keep track of which action each condition belongs to @action = nil + self.behaviors = [] + # the list of conditions for each action self.conditions = {:start => [], :restart => []} end + def behavior(kind) + # create the behavior + begin + b = Behavior.generate(kind) + rescue NoSuchBehaviorError => e + puts e.message + exit + end + + # send to block so config can set attributes + yield(b) if block_given? + + # exit if the Behavior is invalid, the Behavior will have printed + # out its own error messages by now + unless b.valid? + exit + end + + self.behaviors << b + end + def start_if @action = :start yield(self) diff --git a/test/configs/real.rb b/test/configs/real.rb index f80fd66..0932433 100644 --- a/test/configs/real.rb +++ b/test/configs/real.rb @@ -15,6 +15,10 @@ God.meddle do |god| w.grace = 5 pid_file = File.join(RAILS_ROOT, "log/mongrel.pid") + + w.behavior(:clean_pid_file) do |b| + b.pid_file = pid_file + end w.start_if do |start| start.condition(:process_not_running) do |c| @@ -41,7 +45,7 @@ God.meddle do |god| w.name = "local-session-cleanup" w.cwd = File.join(RAILS_ROOT, 'tmp/sessions') w.start = lambda do - p Dir['ruby_sess.*'].select { |f| File.mtime(f) < Time.now - (7 * 24 * 60 * 60) }.each { |f| File.delete(f) } + Dir['ruby_sess.*'].select { |f| File.mtime(f) < Time.now - (7 * 24 * 60 * 60) }.each { |f| File.delete(f) } end w.start_if do |start| diff --git a/test/helper.rb b/test/helper.rb index c0812e7..40566c6 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -16,11 +16,14 @@ module God end class FakeCondition < Condition - def test true end + end + module Behaviors + class FakeBehavior < Behavior + end end end diff --git a/test/test_behavior.rb b/test/test_behavior.rb new file mode 100644 index 0000000..61869b5 --- /dev/null +++ b/test/test_behavior.rb @@ -0,0 +1,9 @@ +require 'helper' + +class TestBehavior < Test::Unit::TestCase + def setup + @behavior = Behavior.new + end + + +end \ No newline at end of file diff --git a/test/test_watch.rb b/test/test_watch.rb index 84ac0ed..342b1de 100644 --- a/test/test_watch.rb +++ b/test/test_watch.rb @@ -74,4 +74,13 @@ class TestWatch < Test::Unit::TestCase end assert_equal 1, @watch.conditions[:start].size end + + # behavior + + def test_behavior_should_record_behavior + beh = nil + @watch.behavior(:fake_behavior) { |b| beh = b } + assert_equal 1, @watch.behaviors.size + assert_equal beh, @watch.behaviors.first + end end \ No newline at end of file -- 2.11.4.GIT