From eca18e072a482f0ba04e6679c0b3935a3a8d357c Mon Sep 17 00:00:00 2001 From: CyberLeo Date: Sat, 22 Nov 2014 04:54:57 -0600 Subject: [PATCH] Split check into web and worker bits to reduce check latency --- Procfile | 1 + app.rb | 2 +- lib/check.rb | 4 +-- lib/checks.rb | 87 +++++++++++++++++++++++++++++++++++++------------- run/.gitignore | 2 ++ worker.rb | 15 +++++++++ 6 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 run/.gitignore create mode 100644 worker.rb diff --git a/Procfile b/Procfile index dc85175..4c4e25f 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ web: bundle exec unicorn -p $PORT -c unicorn.rb +worker: bundle exec ruby worker.rb diff --git a/app.rb b/app.rb index 3a78ebf..9e73be5 100644 --- a/app.rb +++ b/app.rb @@ -1,7 +1,7 @@ require 'sinatra/base' require 'checks' -$checks = Checks.new +$checks = Checks::Web.new class App < Sinatra::Base configure do diff --git a/lib/check.rb b/lib/check.rb index 4d4be78..3af27d9 100644 --- a/lib/check.rb +++ b/lib/check.rb @@ -22,7 +22,7 @@ class Check self.name = params[:name] self.uri = params[:uri] self.timeout = params[:timeout] || 5 - self.max_age = params[:max_age] || 30 + self.max_age = params[:max_age] || 75 end def type @@ -42,7 +42,7 @@ class Check @passed = true end rescue Exception => err - STDERR.puts "#{err.class}: #{err.message}\n#{err.backtrace.join("\n")}" + STDERR.puts "In #{type}(#{name}): #{err.class}: #{err.message}\n#{err.backtrace.join("\n")}" @error = "#{err.class}: #{err.message}" @passed = false end diff --git a/lib/checks.rb b/lib/checks.rb index 3669665..623ca77 100644 --- a/lib/checks.rb +++ b/lib/checks.rb @@ -5,35 +5,78 @@ require 'website_check' class Checks - @@config = "checks.yml" - - def self.config - Configuration.load(@@config) + def self.store_path + @store_path ||= File.expand_path(File.join(File.dirname(__FILE__), "..", "run", "check.dat")) end - def initialize - @checks = [] - end + class Worker + @@config = "checks.yml" - def reload_config - return unless !@config || @config.stale? - @config ||= self.class.config - @checks = @config.map do |check| - Kernel.const_get(check[:class]).new(check) + def self.config + Configuration.load(@@config) end - end - def check - reload_config - threads = @checks.map {|check| Thread.new { check.do_it } } - threads.each(&:join) - end + def initialize + @checks = [] + end + + def reload_config + return unless !@config || @config.stale? + @config ||= self.class.config + @checks = @config.map do |check| + Kernel.const_get(check[:class]).new(check) + end + end + + def check + reload_config + threads = @checks.map {|check| Thread.new { check.do_it } } + threads.each(&:join) + store + end + + def passed? + @checks.map(&:passed?).uniq == [ true ] + end - def passed? - @checks.map(&:passed?).uniq == [ true ] + def results + @checks + end + + def store + File.open(Checks.store_path, File::RDWR|File::CREAT, 0644) do |fp| + fp.flock(File::LOCK_EX) + fp.seek(0) + fp.truncate(0) + fp.write(Marshal.dump(@checks)) + fp.flush + fp.flock(File::LOCK_UN) + end + end end - def results - @checks + class Web + def load + File.open(Checks.store_path, File::RDONLY|File::CREAT, 0644) do |fp| + fp.flock(File::LOCK_SH) + fp.seek(0) + @checks = Marshal.load(fp.read) + fp.flock(File::LOCK_UN) + end + rescue Exception => err + @checks = [] + end + + def check + load + end + + def passed? + @checks.count > 0 && @checks.map(&:passed?).uniq == [ true ] && @checks.map(&:stale?).uniq == [ false ] + end + + def results + @checks + end end end diff --git a/run/.gitignore b/run/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/run/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/worker.rb b/worker.rb new file mode 100644 index 0000000..d29d9e7 --- /dev/null +++ b/worker.rb @@ -0,0 +1,15 @@ +$:.push('lib') +require 'checks' + +$checks = Checks::Worker.new + +pid = nil +while true + $checks.reload_config + Process.kill("TERM", pid) rescue nil if pid + pid = Process.fork do + $checks.check + end + Process.detach(pid) + sleep(60) +end -- 2.45.0