keep_running 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+