From 86eb7ef1bb928016e851a3920b90a0fd6f9df080 Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Mon, 27 Aug 2007 11:29:40 -0700 Subject: [PATCH] Add notify_when_flapping behavior, doc enhancements --- History.txt | 1 + lib/god.rb | 1 + lib/god/behaviors/notify_when_flapping.rb | 53 +++++++++++++++++++++++++++++++ site/index.html | 2 +- test/configs/real.rb | 2 +- test/configs/test.rb | 16 ++++++++-- 6 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 lib/god/behaviors/notify_when_flapping.rb diff --git a/History.txt b/History.txt index f5347fc..5a63f8e 100644 --- a/History.txt +++ b/History.txt @@ -8,6 +8,7 @@ * Bug Fixes * Use exit!(0) instead of exit! in god binary to exit with code 0 (instead of default -1) * Command line group control fixed + * Add :notify_when_flapping behavior to check for oscillation == 0.3.0 / 2007-08-17 diff --git a/lib/god.rb b/lib/god.rb index c0d3e41..acc04e7 100644 --- a/lib/god.rb +++ b/lib/god.rb @@ -9,6 +9,7 @@ require 'god/system/process' require 'god/behavior' require 'god/behaviors/clean_pid_file' +require 'god/behaviors/notify_when_flapping' require 'god/condition' require 'god/conditions/timeline' diff --git a/lib/god/behaviors/notify_when_flapping.rb b/lib/god/behaviors/notify_when_flapping.rb new file mode 100644 index 0000000..0b6a270 --- /dev/null +++ b/lib/god/behaviors/notify_when_flapping.rb @@ -0,0 +1,53 @@ +module God + module Behaviors + + class NotifyWhenFlapping < Behavior + attr_accessor :failures # number of failures + attr_accessor :seconds # number of seconds + attr_accessor :notifier # class to notify with + + def initialize + super + @startup_times = [] + end + + def valid? + valid = true + valid &= complain("You must specify the 'failures' attribute for :notify_when_flapping") unless self.failures + valid &= complain("You must specify the 'seconds' attribute for :notify_when_flapping") unless self.seconds + valid &= complain("You must specify the 'notifier' attribute for :notify_when_flapping") unless self.notifier + + valid &= complain("The 'notifier' attribute must be a class") unless self.notifier.is_a? Class + + # Must take one arg or variable args + unless self.notifier.respond_to?(:notify) and [1,-1].include?(self.notifier.method(:notify).arity) + valid &= complain("The 'notifier' class must have a method 'notify' which takes 1 or variable args") + end + + valid + end + + def before_start + now = Time.now.to_i + @startup_times << now + check_for_flapping(now) + end + + def before_restart + now = Time.now.to_i + @startup_times << now + check_for_flapping(now) + end + + private + + def check_for_flapping(now) + @startup_times = @startup_times.select {|time| time >= now - self.seconds } + if @startup_times.length >= self.failures + self.notifier.notify("#{self.watch.name} has called start/restart #{@startup_times.length} times in #{self.seconds} seconds") + end + end + end + + end +end \ No newline at end of file diff --git a/site/index.html b/site/index.html index aab461b..c63b4b2 100644 --- a/site/index.html +++ b/site/index.html @@ -230,7 +230,7 @@ code {

Requirements

-

God currently only works on Linux (kernel 2.6.15+), BSD, and Darwin systems. No support for Windows is planned.

+

God currently only works on Linux (kernel 2.6.15+), BSD, and Darwin systems. No support for Windows is planned. Event based conditions on Linux systems require the cn (connector) kernel module loaded or compiled in to the kernel and god must be run as root.

The following systems have been tested. Help us test it on others!

diff --git a/test/configs/real.rb b/test/configs/real.rb index 344f9bb..1beaad7 100644 --- a/test/configs/real.rb +++ b/test/configs/real.rb @@ -17,7 +17,7 @@ God.watch do |w| w.behavior(:clean_pid_file) do |b| b.pid_file = pid_file end - + # start if process is not running w.start_if do |start| start.condition(:process_running) do |c| diff --git a/test/configs/test.rb b/test/configs/test.rb index 265c4bd..81c2394 100644 --- a/test/configs/test.rb +++ b/test/configs/test.rb @@ -12,6 +12,12 @@ God.init do |g| # g.pid_file_directory = end +class SimpleNotifier + def self.notify(str) + puts "Notifying: #{str}" + end +end + God.watch do |w| w.name = "local-3000" w.interval = 5.seconds @@ -21,14 +27,20 @@ God.watch do |w| w.restart_grace = 5.seconds w.stop_grace = 5.seconds w.autostart = true - w.uid = 'tom' - w.gid = 'tom' + w.uid = 'kev' + w.gid = 'kev' w.group = 'mongrels' w.pid_file = File.join(RAILS_ROOT, "log/mongrel.pid") # clean pid files before start if necessary w.behavior(:clean_pid_file) + w.behavior(:notify_when_flapping) do |b| + b.failures = 5 + b.seconds = 60.seconds + b.notifier = SimpleNotifier + end + # determine the state on startup w.transition(:init, { true => :up, false => :start }) do |on| on.condition(:process_running) do |c| -- 2.11.4.GIT