From c20b420d4a9f8d9712b08789b877d9bf55692dfa Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Wed, 3 Mar 2010 17:04:19 +0100 Subject: [PATCH 01/20] Default value fuer max=10 or range=10, if it will be nil. --- lib/robustserver.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 8a63a4d..01d3109 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -33,8 +33,8 @@ class Retries attr_accessor :max, :range attr_reader :count, :last - def initialize max = 10, range = 10 - @max, @range, @count, @last = max, range, 0, Time.now + def initialize max = nil, range = nil + @max, @range, @count, @last = max || 10, range || 10, 0, Time.now end def retry? From aa47581eb978ab2640df7a2dbcbe863b28447880 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Sun, 7 Mar 2010 19:30:33 +0100 Subject: [PATCH 02/20] Signalhandler mit Puffer. --- VERSION | 2 +- lib/robustserver.rb | 7 ++++++- robustserver.gemspec | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 77d6f4c..0e81df0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.0 +0.0.0.1 diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 01d3109..4b7d51d 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -52,6 +52,8 @@ class Retries end class RobustServer + attr_reader :signals + def self.main *argv self.new( *argv).main end @@ -62,6 +64,7 @@ class RobustServer Signal[:INT] => sh, Signal[:HUP] => nil, Signal[:TERM] => sh, Signal[:KILL] => sh, Signal[:USR1] => nil, Signal[:USR2] => nil } + @signals = [] end def trapping @@ -69,7 +72,8 @@ class RobustServer end def signal_handler s - @signal = s + s = s + @signals.push s unless @signals.include? s end def main max = nil, range = nil @@ -85,6 +89,7 @@ class RobustServer retry if retries.retry? $stderr.print "Zuviele Fehler in zu kurzer Zeit. Ich gebe auf und " end + $stderr.puts "Unbeachtete Signale: #{@signals.map(&Signal.method(:[])).join( ', ')}" trapping $stderr.puts "Beende mich selbst." end diff --git a/robustserver.gemspec b/robustserver.gemspec index e6892d2..dcd3257 100644 --- a/robustserver.gemspec +++ b/robustserver.gemspec @@ -5,11 +5,11 @@ Gem::Specification.new do |s| s.name = %q{robustserver} - s.version = "0.0.0" + s.version = "0.0.0.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Denis Knauf"] - s.date = %q{2010-03-02} + s.date = %q{2010-03-07} s.description = %q{Protects your Server against SIGS and unplaned exceptions} s.email = %q{Denis.Knauf@gmail.com} s.extra_rdoc_files = [ From 0d4506941e400d6c0f0c88793a31664abc3bc4ac Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Sun, 7 Mar 2010 21:30:43 +0100 Subject: [PATCH 03/20] Signalhandler mit Ausgabe. --- lib/robustserver.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 4b7d51d..7162a5c 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -72,6 +72,7 @@ class RobustServer end def signal_handler s + $stderr.puts [:signal, s, Signal[s]].inspect s = s @signals.push s unless @signals.include? s end From c992701299bedb2d9c444aab2a6ce735e7c10ee9 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 11 Mar 2010 00:23:20 +0100 Subject: [PATCH 04/20] Version 0.0.1. Only changes for gemcutter --- Rakefile | 2 +- VERSION | 2 +- robustserver.gemspec | 40 ---------------------------------------- 3 files changed, 2 insertions(+), 42 deletions(-) delete mode 100644 robustserver.gemspec diff --git a/Rakefile b/Rakefile index 00f3418..9e28dbe 100644 --- a/Rakefile +++ b/Rakefile @@ -6,7 +6,7 @@ begin Jeweler::Tasks.new do |gem| gem.name = "robustserver" gem.summary = %Q{Robust Server} - gem.description = %Q{Protects your Server against SIGS and unplaned exceptions} + gem.description = %Q{Protects your Server against SIGS and rescues all exceptions.} gem.email = "Denis.Knauf@gmail.com" gem.homepage = "http://github.com/DenisKnauf/robustserver" gem.authors = ["Denis Knauf"] diff --git a/VERSION b/VERSION index 0e81df0..8acdd82 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.0.1 +0.0.1 diff --git a/robustserver.gemspec b/robustserver.gemspec deleted file mode 100644 index dcd3257..0000000 --- a/robustserver.gemspec +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by jeweler -# DO NOT EDIT THIS FILE DIRECTLY -# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command -# -*- encoding: utf-8 -*- - -Gem::Specification.new do |s| - s.name = %q{robustserver} - s.version = "0.0.0.1" - - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Denis Knauf"] - s.date = %q{2010-03-07} - s.description = %q{Protects your Server against SIGS and unplaned exceptions} - s.email = %q{Denis.Knauf@gmail.com} - s.extra_rdoc_files = [ - "LICENSE", - "README.md" - ] - s.files = [ - "README.md", - "VERSION", - "lib/robustserver.rb" - ] - s.homepage = %q{http://github.com/DenisKnauf/robustserver} - s.rdoc_options = ["--charset=UTF-8"] - s.require_paths = ["lib"] - s.rubygems_version = %q{1.3.5} - s.summary = %q{Robust Server} - - if s.respond_to? :specification_version then - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION - s.specification_version = 3 - - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then - else - end - else - end -end - From 899a1dd39977b24c6f4afc10b8b734edbc1a9da6 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 11 Mar 2010 11:32:27 +0100 Subject: [PATCH 05/20] First comments for Retries and RobustServer. --- lib/robustserver.rb | 49 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 7162a5c..ce1e968 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -4,6 +4,7 @@ def Signal.signame s when String then s when Symbol then s.to_s when Fixnum then list.invert[s] + else raise ArgumentError, "String, Symbol or Fixnum expected, not #{s.class}" end end @@ -12,6 +13,7 @@ def Signal.sig s when Fixnum then s when String then list[s] when Symbol then list[s.to_s] + else raise ArgumentError, "String, Symbol or Fixnum expected, not #{s.class}" end end @@ -25,25 +27,58 @@ def Signal.[] s when String then list[s] when Symbol then list[s.to_s] when Fixnum then list.invert[s] - else raise ArgumentError + else raise ArgumentError, "String, Symbol or Fixnum expected, not #{s.class}" end end +# Counts retries ot something. If the retries are to often in a short time, +# you shouldn't retry again. +# +# Example: +# retries = Retry.new 5, 1 +# begin +# array_of_ints_and_some_strings.each do |i| +# puts 2*i +# end +# rescue TypeError +# retries.retry? and retry +# raise $! +# end +# +# Retry.new( 10, 30).run( ConnectionLost) do +# try_to_connect_to_db +# try_query +# end class Retries attr_accessor :max, :range attr_reader :count, :last + # max: How many retries in range-time are allowed maximal. + # range: In which time-range are these retries are allowed def initialize max = nil, range = nil @max, @range, @count, @last = max || 10, range || 10, 0, Time.now end + # Counts retries on every call. + # If these retries are to often - max times in range - it will return false + # else true. + # Now you can say: "I give up, to many retries, it seems it doesn't work." def retry? @count = @last + @range > Time.now ? @count + 1 : 1 @last = Time.now @count < @max end - def run ex, &e + # Automatical retrieing on raised exceptions in block. + # ex: Your expected Esception you will rescue. Default: Object, so realy everything. + # + # Example: + # Retries.new( 10, 30).run ArgumentError do something_do_which_could_raise_exception ArgumentError end + # + # This will retry maximal 10 times in 30 seconds to Call this block. But only rescues ArgumentError! + # Every other Error it will ignore and throws Exception. No retry. + def run ex = nil, &e + ex ||= Object begin e.call *args rescue ex retries.retry? and retry @@ -51,6 +86,16 @@ class Retries end end +# Easy problem-handler for your Server. +# +# A Server should never crash. +# If an Exception raised, which is not rescued, your program will shutdown abnormaly. +# Or if a signal tries to "kill" your program, your program will shutdown abnormaly too. +# +# With RobustServer these errors will be a more unimportant problem and It'll be easier to handle. +# +# Subclasses should implements *#run*, which will be your main-worker. +# For initializing, you can override **#initialize**, but doen't forget to call **super**. class RobustServer attr_reader :signals From e11976f9a29a6f7c5937f4b51bddfb5d830c0913 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Wed, 17 Mar 2010 13:26:24 +0100 Subject: [PATCH 06/20] More docs --- lib/robustserver.rb | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index ce1e968..b456d25 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -31,24 +31,31 @@ def Signal.[] s end end +# Description +# =========== +# # Counts retries ot something. If the retries are to often in a short time, # you shouldn't retry again. # -# Example: -# retries = Retry.new 5, 1 -# begin -# array_of_ints_and_some_strings.each do |i| -# puts 2*i -# end -# rescue TypeError -# retries.retry? and retry -# raise $! -# end +# Examples +# ======== +# +# Strings aren't Integers and 2*"Text" will raise TypeError. # -# Retry.new( 10, 30).run( ConnectionLost) do -# try_to_connect_to_db -# try_query -# end +# retries = Retry.new 5, 1 +# begin +# array_of_ints_and_some_strings.each do |i| +# puts 2*i +# end +# rescue TypeError +# retries.retry? and retry +# raise $! +# end +# +# Retry.new( 10, 30).run( ConnectionLost) do +# try_to_connect_to_db +# try_query +# end class Retries attr_accessor :max, :range attr_reader :count, :last From 5169bee0eaa0cd23485d8f77dbe5d69ba21d83e6 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Sat, 20 Mar 2010 23:22:53 +0100 Subject: [PATCH 07/20] little changes: metafiles --- AUTHOR => AUTHORS | 0 Rakefile | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename AUTHOR => AUTHORS (100%) diff --git a/AUTHOR b/AUTHORS similarity index 100% rename from AUTHOR rename to AUTHORS diff --git a/Rakefile b/Rakefile index 9e28dbe..2b6eb89 100644 --- a/Rakefile +++ b/Rakefile @@ -10,8 +10,8 @@ begin gem.email = "Denis.Knauf@gmail.com" gem.homepage = "http://github.com/DenisKnauf/robustserver" gem.authors = ["Denis Knauf"] - gem.files = ["AUTHORS", "README.md", "VERSION", "lib/**/*.rb", "test/**/*.rb"] - gem.require_paths = ["lib"] + gem.files = %w[AUTHORS README.md VERSION lib/**/*.rb test/**/*.rb] + gem.require_paths = %w[lib] end Jeweler::GemcutterTasks.new rescue LoadError From 5ef72caa6b4c38bdefabd4c520557382f90c425d Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Sun, 21 Mar 2010 20:58:42 +0100 Subject: [PATCH 08/20] at_exit added. use it to clean your dishes. --- lib/robustserver.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index b456d25..6628114 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -144,6 +144,10 @@ class RobustServer end $stderr.puts "Unbeachtete Signale: #{@signals.map(&Signal.method(:[])).join( ', ')}" trapping + self.at_exit $stderr.puts "Beende mich selbst." end + + def at_exit + end end From 56070055d8100e00dfb01f8233270fe12ccf9c22 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Sun, 21 Mar 2010 20:59:39 +0100 Subject: [PATCH 09/20] this new at_exit is ready. new version! --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 8acdd82..4e379d2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1 +0.0.2 From fc48ded7ba00e3db033028f166567f657dacba51 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 12:01:57 +0200 Subject: [PATCH 10/20] Rakefile updated. --- Rakefile | 78 +++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/Rakefile b/Rakefile index 2b6eb89..06cfb4f 100644 --- a/Rakefile +++ b/Rakefile @@ -1,57 +1,49 @@ +# encoding: utf-8 + require 'rubygems' +require 'bundler' +begin + Bundler.setup(:default, :development) +rescue Bundler::BundlerError => e + $stderr.puts e.message + $stderr.puts "Run `bundle install` to install missing gems" + exit e.status_code +end require 'rake' -begin - require 'jeweler' - Jeweler::Tasks.new do |gem| - gem.name = "robustserver" - gem.summary = %Q{Robust Server} - gem.description = %Q{Protects your Server against SIGS and rescues all exceptions.} - gem.email = "Denis.Knauf@gmail.com" - gem.homepage = "http://github.com/DenisKnauf/robustserver" - gem.authors = ["Denis Knauf"] - gem.files = %w[AUTHORS README.md VERSION lib/**/*.rb test/**/*.rb] - gem.require_paths = %w[lib] - end - Jeweler::GemcutterTasks.new -rescue LoadError - puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler" +require 'jeweler' +Jeweler::Tasks.new do |gem| + # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options + gem.name = "robustserver" + gem.summary = %Q{Robust Server} + gem.description = %Q{Protects your Server against SIGS and rescues all exceptions.} + gem.email = "Denis.Knauf@gmail.com" + gem.homepage = "http://github.com/DenisKnauf/robustserver" + gem.authors = ["Denis Knauf"] + gem.files = %w[AUTHORS README.md VERSION lib/**/*.rb test/**/*.rb] + gem.require_paths = %w[lib] + # dependencies defined in Gemfile end +Jeweler::RubygemsDotOrgTasks.new require 'rake/testtask' Rake::TestTask.new(:test) do |test| - test.libs << 'lib' << 'test' << 'ext' - test.pattern = 'test/**/*_test.rb' + test.libs << 'lib' << 'test' + test.pattern = 'test/**/test_*.rb' test.verbose = true end -begin - require 'rcov/rcovtask' - Rcov::RcovTask.new do |test| - test.libs << 'test' - test.pattern = 'test/**/*_test.rb' - test.verbose = true - end -rescue LoadError - task :rcov do - abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov" - end +=begin +require 'rcov/rcovtask' +Rcov::RcovTask.new do |test| + test.libs << 'test' + test.pattern = 'test/**/test_*.rb' + test.verbose = true + test.rcov_opts << '--exclude "gems/*"' end - -task :test => :check_dependencies +=end task :default => :test -require 'rake/rdoctask' -Rake::RDocTask.new do |rdoc| - if File.exist?('VERSION') - version = File.read('VERSION') - else - version = "" - end - - rdoc.rdoc_dir = 'rdoc' - rdoc.title = "sbdb #{version}" - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') -end +require 'yard' +YARD::Rake::YardocTask.new From 9551fbe35ddc0c95e5497fb685dc196d394479b9 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 12:04:12 +0200 Subject: [PATCH 11/20] translated (english). $stderr -> output (default $stderr). #run / #loop dummies (#loop will be called by #run in a loop, if #run not overwritten. SystemExit will be reraised. --- lib/robustserver.rb | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 6628114..26d1efa 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -104,19 +104,19 @@ end # Subclasses should implements *#run*, which will be your main-worker. # For initializing, you can override **#initialize**, but doen't forget to call **super**. class RobustServer - attr_reader :signals + attr_reader :signals, :output def self.main *argv self.new( *argv).main end - def initialize *p + def initialize *_ sh = method :signal_handler @sigs = { Signal[:INT] => sh, Signal[:HUP] => nil, Signal[:TERM] => sh, Signal[:KILL] => sh, Signal[:USR1] => nil, Signal[:USR2] => nil } - @signals = [] + @signals, @output = [], $stderr end def trapping @@ -124,7 +124,7 @@ class RobustServer end def signal_handler s - $stderr.puts [:signal, s, Signal[s]].inspect + output.puts [:signal, s, Signal[s]].inspect s = s @signals.push s unless @signals.include? s end @@ -132,20 +132,33 @@ class RobustServer def main max = nil, range = nil retries = Retries.new max, range trapping - $stderr.puts "Arbeit wird nun aufgenommen..." + output.puts "Running...." begin self.run - rescue SystemExit, Interrupt, SignalException - $stderr.puts "Das Beenden des Programms wurde angefordert. #{$!}" + rescue SystemExit + output.puts "Server interrupted by signal: #$!" + raise + rescue Interrupt, SignalException + output.puts "Server interrupted by signal: #$!" + exit 0 rescue Object - $stderr.puts [:rescue, $!, $!.class, $!.backtrace].inspect + output.puts [:rescue, $!, $!.class, $!.backtrace].inspect retry if retries.retry? - $stderr.print "Zuviele Fehler in zu kurzer Zeit. Ich gebe auf und " + output.print "Too many errors in too short time. Give up: " end - $stderr.puts "Unbeachtete Signale: #{@signals.map(&Signal.method(:[])).join( ', ')}" + ensure + output.puts "Disregarded signals: #{@signals.map(&Signal.method(:[])).join( ', ')}" trapping self.at_exit - $stderr.puts "Beende mich selbst." + output.puts "Shutdown." + end + + def run + Kernel.loop &method( :loop) + end + + def loop + raise Exception, "You must implement #{self.class.name}#run or #{self.class.name}#loop." end def at_exit From f11b7df104ee3fc9e8b4c6e061ea98aac060d0e0 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 12:06:24 +0200 Subject: [PATCH 12/20] Gemfile and gemspec generated --- Gemfile | 12 ++++++++++ Gemfile.lock | 46 +++++++++++++++++++++++++++++++++++ robustserver.gemspec | 57 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 robustserver.gemspec diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..1934d03 --- /dev/null +++ b/Gemfile @@ -0,0 +1,12 @@ +source "http://rubygems.org" + +# Add dependencies to develop your gem here. +# Include everything needed to run rake, tests, features, etc. +group :development do + gem "shoulda" + gem "yard" + gem "rdoc" + gem "bundler" + gem "jeweler" + gem "simplecov" +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..4f0c120 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: http://rubygems.org/ + specs: + activesupport (3.2.13) + i18n (= 0.6.1) + multi_json (~> 1.0) + bourne (1.4.0) + mocha (~> 0.13.2) + git (1.2.5) + i18n (0.6.1) + jeweler (1.8.4) + bundler (~> 1.0) + git (>= 1.2.5) + rake + rdoc + json (1.7.7) + metaclass (0.0.1) + mocha (0.13.3) + metaclass (~> 0.0.1) + multi_json (1.7.2) + rake (10.0.4) + rdoc (4.0.1) + json (~> 1.4) + shoulda (3.4.0) + shoulda-context (~> 1.0, >= 1.0.1) + shoulda-matchers (~> 1.0, >= 1.4.1) + shoulda-context (1.1.0) + shoulda-matchers (1.5.6) + activesupport (>= 3.0.0) + bourne (~> 1.3) + simplecov (0.7.1) + multi_json (~> 1.0) + simplecov-html (~> 0.7.1) + simplecov-html (0.7.1) + yard (0.8.5.2) + +PLATFORMS + ruby + +DEPENDENCIES + bundler + jeweler + rdoc + shoulda + simplecov + yard diff --git a/robustserver.gemspec b/robustserver.gemspec new file mode 100644 index 0000000..6f548c4 --- /dev/null +++ b/robustserver.gemspec @@ -0,0 +1,57 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "robustserver" + s.version = "0.0.2" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Denis Knauf"] + s.date = "2013-04-15" + s.description = "Protects your Server against SIGS and rescues all exceptions." + s.email = "Denis.Knauf@gmail.com" + s.extra_rdoc_files = [ + "LICENSE", + "README.md" + ] + s.files = [ + "AUTHORS", + "README.md", + "VERSION", + "lib/robustserver.rb" + ] + s.homepage = "http://github.com/DenisKnauf/robustserver" + s.require_paths = ["lib"] + s.rubygems_version = "1.8.23" + s.summary = "Robust Server" + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end + From d7edbb750e0730d8415fb26e2b79c7ac1f5e08ef Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 12:11:55 +0200 Subject: [PATCH 13/20] #loop was a bad idea. #run raises UnimplementedRun. on UnimplementedRun main will never retry. --- lib/robustserver.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 26d1efa..57b4efc 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -104,6 +104,8 @@ end # Subclasses should implements *#run*, which will be your main-worker. # For initializing, you can override **#initialize**, but doen't forget to call **super**. class RobustServer + class UnimplementedRun Date: Mon, 15 Apr 2013 12:13:23 +0200 Subject: [PATCH 14/20] exception -> exit(2). unimplemented -> message+exit(1) --- lib/robustserver.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 57b4efc..41ae003 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -138,7 +138,8 @@ class RobustServer begin self.run rescue UnimplementedRun - raise + output.puts $!.message + exit 1 rescue SystemExit output.puts "Server interrupted by signal: #$!" raise @@ -149,6 +150,7 @@ class RobustServer output.puts [:rescue, $!, $!.class, $!.backtrace].inspect retry if retries.retry? output.print "Too many errors in too short time. Give up: " + exit 2 end ensure output.puts "Disregarded signals: #{@signals.map(&Signal.method(:[])).join( ', ')}" From 37ac8bb3db2c926f74bfee898b0ea53e8d4ddef4 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 12:19:23 +0200 Subject: [PATCH 15/20] only display disregarded signals, if there are disregarded signals --- lib/robustserver.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 41ae003..8008b99 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -153,7 +153,7 @@ class RobustServer exit 2 end ensure - output.puts "Disregarded signals: #{@signals.map(&Signal.method(:[])).join( ', ')}" + output.puts "Disregarded signals: #{@signals.map(&Signal.method(:[])).join( ', ')}" unless @signals.empty? trapping self.at_exit output.puts "Shutdown." From 5b7d63fb2db35f248d6ff17efbe54326855dceef Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 16:11:26 +0200 Subject: [PATCH 16/20] s = s removed --- lib/robustserver.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 8008b99..4ecc63f 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -127,7 +127,6 @@ class RobustServer def signal_handler s output.puts [:signal, s, Signal[s]].inspect - s = s @signals.push s unless @signals.include? s end From c34cc60ae64c08a7ffa8f0a57e5b5de78d932fb7 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 16:16:17 +0200 Subject: [PATCH 17/20] Version bump to 0.0.3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4e379d2..6812f81 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.2 +0.0.3 \ No newline at end of file From f09d6150dded9969523d26abc16f3f126dfe0d69 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 16:16:21 +0200 Subject: [PATCH 18/20] Regenerate gemspec for version 0.0.3 --- robustserver.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robustserver.gemspec b/robustserver.gemspec index 6f548c4..7ffa2ee 100644 --- a/robustserver.gemspec +++ b/robustserver.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "robustserver" - s.version = "0.0.2" + s.version = "0.0.3" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Denis Knauf"] From 0e90737ae1e860ff2677cf0154f92c38497390c3 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 15 Apr 2013 16:17:31 +0200 Subject: [PATCH 19/20] ignore pkg and vi-tempfiles --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf08465 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.*.swp +pkg From 92060db9947b6bcf27630b985415505379fd84dd Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Tue, 30 Nov 2021 14:09:35 +0100 Subject: [PATCH 20/20] More readable description for RobusServer-class. --- lib/robustserver.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/robustserver.rb b/lib/robustserver.rb index 4ecc63f..91fc1d9 100644 --- a/lib/robustserver.rb +++ b/lib/robustserver.rb @@ -95,14 +95,15 @@ end # Easy problem-handler for your Server. # -# A Server should never crash. -# If an Exception raised, which is not rescued, your program will shutdown abnormaly. -# Or if a signal tries to "kill" your program, your program will shutdown abnormaly too. +# Problem: Your process should not crash, it should be available for anytime. +# If an exception will be raised, you have to handle it, or it will be shutdown abnormaly. +# Or if a signal tries to "kill" your program, your program will shutdown abnormaly, too. # -# With RobustServer these errors will be a more unimportant problem and It'll be easier to handle. +# RobustServer handles any exception / kill, logs it and prevents the server to shutting down. # -# Subclasses should implements *#run*, which will be your main-worker. -# For initializing, you can override **#initialize**, but doen't forget to call **super**. +# For implementation a server, create a subclass of RobustServer and implement the *#run*-method. +# Anytime this *#run*-method returns or an exception will be raised, it will be rescued and run recalled. +# For initialization, you can override **#initialize**, but don't forget to call **super**. class RobustServer class UnimplementedRun