Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby daemon with clean shutdown

Tags:

ruby

daemon

I would like to make a ruby daemon that would gracefully shutdown with a kill command. I would like to add a signal trap that would wait until #code that could take some time to run finishes before shutting down. How would I add that to something like this:

pid = fork do
   pid_file = "/tmp/pids/daemon6.pid"
   File.open(pid, 'w'){ |f| f.write(Process.pid) }
   loop do
      begin
         #code that could take some time to run
      rescue Exception => e
         Notifier.deliver_daemon_rescued_notification(e)
      end
      sleep(10)
   end
end
Process.detach pid

Also, would it be better to have that in a separate script, like a separate kill script instead of having it as part of the daemon code? Like something monit or God would call to stop it?

I appreciate any suggestions.

like image 484
fflyer05 Avatar asked Apr 26 '11 16:04

fflyer05


Video Answer


1 Answers

You can catch Interrupt, like this:

pid = fork do
  begin
    loop do
      # do your thing
      sleep(10)
    end
  rescue Interrupt => e
    # clean up
  end
end
Process.detach(pid)

You can do the same with Signal.trap('INT') { ... }, but with sleep involved I think it's easier to catch an exception.

Update: this is a more traditional way of doing it, and it makes sure the loop always finishes a complete go before it stops:

pid = fork do
  stop = false
  Signal.trap('INT') { stop = true }
  until stop
    # do your thing
    sleep(10)
  end
end

The downside is that it will always do the sleep, so there will almost always be a delay until the process stops after you've killed it. You can probably get around that by sleeping in bursts, or doing a combination of the variants (rescuing the Interrupt just around the sleep or something).

like image 165
Theo Avatar answered Sep 22 '22 15:09

Theo