how to controller (start/kill) a background process (server app) in ruby how to controller (start/kill) a background process (server app) in ruby ruby ruby

how to controller (start/kill) a background process (server app) in ruby


The standard way is to use the system functions fork (to duplicate the current process), exec (to replace the current process by an executable file), and kill (to send a signal to a process to terminate it).

For example :

pid = fork do  # this code is run in the child process  # you can do anything here, like changing current directory or reopening STDOUT  exec "/path/to/executable"end# this code is run in the parent process# do your stuffs# kill it (other signals than TERM may be used, depending on the program you want# to kill. The signal KILL will always work but the process won't be allowed# to cleanup anything)Process.kill "TERM", pid# you have to wait for its termination, otherwise it will become a zombie process# (or you can use Process.detach)Process.wait pid

This should work on any Unix like system. Windows creates process in a different way.


I just had to do something similar and this is what I came up with. @Michael Witrant's answer got me started, but I changed some things like using Process.spawn instead of fork (newer and better).

# start spawns a process and returns the pid of the processdef start(exe)    puts "Starting #{exe}"    pid = spawn(exe)    # need to detach to avoid daemon processes: http://www.ruby-doc.org/core-2.1.3/Process.html#method-c-detach    Process.detach(pid)    return pidend# This will kill off all the programs we starteddef killall(pids)  pids.each do |pid|      puts "Killing #{pid}"      # kill it (other signals than TERM may be used, depending on the program you want      # to kill. The signal KILL will always work but the process won't be allowed      # to cleanup anything)      begin        Process.kill "TERM", pid        # you have to wait for its termination, otherwise it will become a zombie process        # (or you can use Process.detach)        Process.wait pid      rescue => ex        puts "ERROR: Couldn't kill #{pid}. #{ex.class}=#{ex.message}"      end  endend# Now we can start processes and keep the pids for killing them laterpids = []pids << start('./someprogram')# Do whatever you want here, run your tests, etc. # When you're done, be sure to kill of the processes you spawnedkillall(pids)

That's about all she wrote, give it a try and let me know how it works.


I have tried fork, but it has kind of problems when ActiveRecord is involved in both the processes. I would suggest Spawn plugin (http://github.com/tra/spawn). It does fork only but takes care of ActiveRecord.