Search code examples
rubybashzeromqworker

How to manage ruby workers processes for start, stop and restart?


I have many workers like this :

Client.rb                      Worker.rb
 |                              |
 |- Client1.rb <=>          <=> |- Worker1.rb   
 |- Client2.rb <=> Proxy.rb <=> |- Worker2.rb
 |- Client3.rb <=>          <=> |- Worker3.rb

The inter-process communication is done with ZMQ

Actually, i start all process in background with this bash script :

#!/bin/bash

ruby Proxy.rb &
ruby Worker.rb &
ruby Client.rb &

For example, this script force me to use "kill" command for stop all processes ... It's not fun.

How can i start, stop, restart all process like a service ?


Solution

  • It sounds like you want a process monitoring system. There are many solutions to this, for example

    • monit
    • bluepill
    • god

    I've used god most recently. With god create a configuration file that defines each worker, how to stop/start it and when it should be restarted automatically (eg if it is using too much memory)

    As long as you can setup your scripts to drop a pidfile at a predictable location then it's pretty easy. For example if your god config file contained

    ROOT = "/folder/containing/files"
    
    3.times do |num|
      God.watch do |w|
        w.group = "workers" 
        w.name = "worker-#{num}"
        w.dir = ROOT
        w.start = "ruby ./Worker.rb --pid tmp/pids/worker.#{num}.pid "
        w.pid_file = File.join(ROOT, "tmp/pids/worker.#{num}.pid") 
        w.behavior(:clean_pid_file)
    
        w.start_if do |start|
          start.condition(:process_running) do |c|
            c.interval = 5.seconds
            c.running = false
          end
        end
      end
    end
    

    then god start worker-0 (or stop, restart) would act on the first worker, whereas god start workers would start all 3 workers (and start them again if they crashed). You would need to change your script to write its pid file to the location indicated by the --pid argument