Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
(Insanity Radio) Ruby script to monitor Rotter, restart it if it dies, and ensure that is always writing output.
#!/usr/bin/env ruby
# Super simple daemon to watch Rotter and ensure it doesn't crash
$config = {
:path => "/var/www/",
:timeout => 5,
:log => "/dev/null"
:pid => "/run/insanity-rotter.pid" }
begin
pid = File.read($config[:pid]).to_i
Process.kill 0, pid
abort "[ CRIT ] Script is already running with PID #{pid}. Kill it first."
rescue
end
abort "[ CRIT ] Try re-running as superuser" if Process.euid != 0 or (pid = fork) == -1
exit unless pid.nil?
Process.setsid
abort "[ CRIT ] For some reason the second fork failed" if (pid = fork) == -1
exit unless pid.nil?
Dir.chdir "/"
STDIN.reopen "/dev/null"
STDOUT.reopen $config[:log], "a"
STDERR.reopen STDOUT
puts "[ INFO ] Started with PID #{Process.pid}"
File.write $config[:pid], Process.pid
# We're forked! Start our monitoring.
Thread.new do
loop do
file_name = Time.now.strftime("#{$config[:path]}%Y-%m-%d/%Y-%m-%d-%H.mp3")
initial_size = File.size(file_name)
sleep $config[:timeout]
# if we've moved into the next hour, we no longer care
next if file_name != Time.now.strftime("#{$config[:path]}%Y-%m-%d/%Y-%m-%d-%H.mp3")
# magic: if the soundcard has died, the file size won't change by much.
if initial_size + 10 > File.size(file_name)
STDERR.puts "[ CRIT ] Restarting Rotter, file writing stopped"
Process.kill "TERM", $pid
sleep $config[:timeout]
end
end
end
loop do
$pid = fork { exec "rotter -a -f mp3 -b 320 -L dailydir #{$config[:path]}" }
puts "[ INFO ] Rotter started"
Process.waitpid($pid)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment