keep_running 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.join( File.dirname(__FILE__), '../lib')
4
+
5
+ require 'keep_running'
6
+
7
+ KeepRunning.load_runner File.expand_path(ARGV[0])
@@ -0,0 +1,115 @@
1
+ require 'fileutils'
2
+ require 'pony'
3
+
4
+ class KeepRunning
5
+ class << self
6
+ def load_runner(runner)
7
+ load @runner_location = runner
8
+ end
9
+
10
+ def runner_location
11
+ @runner_location ||= File.expand_path($0)
12
+ end
13
+
14
+ def process_argv
15
+ ARGV.shift if File.basename($0) == 'keep_running'
16
+ end
17
+
18
+ def run(&block)
19
+ runner = new
20
+ process_argv
21
+ runner.instance_eval &block
22
+ runner.run
23
+ end
24
+ end
25
+
26
+ def pidfile(p) ; @pidfile = p ; end
27
+ def email(e) ; @email_opts = e ; end
28
+ def restart_threshold(t) ; @restart_threshold = t ; end
29
+ def restart_delay(d) ; @restart_delay = d ; end
30
+ def process(p)
31
+ @process = File.expand_path(File.join(File.dirname(self.class.runner_location), p))
32
+ end
33
+
34
+ def run
35
+ write_pidfile
36
+
37
+ output = nil
38
+ loop do
39
+ output = spawn { start_process } # load the given script
40
+ send_mail subject(@process), output # send the email
41
+ throttle_restart # don't restart too fast
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def start_process
48
+ if File.extname(@process) == '.rb'
49
+ load @process
50
+ else
51
+ puts 'only spawning of ruby processes supported'
52
+ end
53
+ end
54
+
55
+ def add_exit_hook(pid)
56
+ at_exit do
57
+ Process.kill 'QUIT', pid rescue nil # ensure the child exits
58
+ sleep 1 # give it some time
59
+ Process.kill 'KILL', pid rescue nil # really ensure the child exits
60
+ end
61
+ end
62
+
63
+ def send_mail(subject, body)
64
+ Pony.mail @email_opts.update(:subject => subject(@process), :body => body)
65
+ end
66
+
67
+ def write_pidfile
68
+ puts "wrote PID-file #{@pidfile}"
69
+ File.open(@pidfile, 'w'){|file| file << Process.pid }
70
+ at_exit{
71
+ if File.new(@pidfile, "r").gets.to_i == Process.pid
72
+ FileUtils.rm @pidfile rescue nil
73
+ end
74
+ }
75
+ end
76
+
77
+ def spawn
78
+ readme, writeme = IO.pipe # open an pipe for the child to write in, the parent to read
79
+ pid = fork{ |variable| # fork the process
80
+ $stdout.reopen writeme # reopen the child end of the pipe
81
+ $stderr.reopen writeme # reopen the child end of the pipe
82
+ readme.close # close the parent end of the pipe in the child
83
+ yield # YIELD the given block
84
+ }
85
+ writeme.close # close the child end of the pipe in the parent
86
+ puts "forked child as PID #{pid}"
87
+
88
+ add_exit_hook pid
89
+
90
+ output = []
91
+ readme.each{ |line|
92
+ output = output[-1000,1000] || [] # truncate the output array
93
+ puts line
94
+ output << line # collect the childs stdout
95
+ }
96
+
97
+ Process.waitpid pid, 0 # wait for the child to exit
98
+ return output.join
99
+ end
100
+
101
+ def throttle_restart
102
+ if @last_exit && Time.now - @last_exit < @restart_threshold
103
+ puts "Last restart was less than #{@restart_threshold} seconds ago: #{@last_exit}."
104
+ puts "Sleeping some #{@restart_delay} seconds..."
105
+ sleep @restart_delay
106
+ puts "Let's try again."
107
+ end
108
+ @last_exit = Time.now
109
+ end
110
+
111
+ def subject(script)
112
+ "#{script} ended (PID #{Process.pid} on #{`hostname`.strip})"
113
+ end
114
+
115
+ end
@@ -0,0 +1,3 @@
1
+ class KeepRunning
2
+ VERSION = '0.0.4'
3
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keep_running
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.4
6
+ platform: ruby
7
+ authors:
8
+ - Niko Dittmann
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-12-13 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: pony
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ description: a script to restart other scripts whenever they crash, stop, get killed. It sends emails, when restart occurs.
27
+ email: mail+git@niko-dittmann.com
28
+ executables:
29
+ - keep_running
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - lib/keep_running/version.rb
36
+ - lib/keep_running.rb
37
+ - bin/keep_running
38
+ homepage: http://github.com/niko/keep_running
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.11
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: a script to restart other scripts whenever they crash, stop, get killed.
65
+ test_files: []
66
+