aboutsummaryrefslogtreecommitdiffstats
path: root/railties/bin/process/spinner
blob: ff7a57616321c0367bbc3922082d37ad46cf87bc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/local/bin/ruby

require 'optparse'

def daemonize
  exit if fork                   # Parent exits, child continues.
  Process.setsid                 # Become session leader.
  exit if fork                   # Zap session leader. See [1].
  Dir.chdir "/"                  # Release old working directory.
  File.umask 0000                # Ensure sensible umask. Adjust as needed.
  STDIN.reopen "/dev/null"       # Free file descriptors and
  STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
  STDERR.reopen STDOUT           # STDOUT/ERR should better go to a logfile.
end

OPTIONS = {
  :interval   => 1.0,
  :command    => File.expand_path(File.dirname(__FILE__) + '/spawner'),
  :daemon     => false
}

ARGV.options do |opts|
  opts.banner = "Usage: spinner [options]"

  opts.separator ""

  opts.on <<-EOF
  Description:
    The spinner is a protection loop for the spawner, which will attempt to restart any FCGI processes
    that might have been restarted or outright crashed. It's a brute-force attempt that'll just try
    to run the spawner every X number of seconds, so it does pose a load on the server (~1% on our test
    server).    

  Examples:
    spinner # attempts to run the spawner with default settings every second with output on the terminal
    spinner -i 3 -d # only run the spawner every 3 seconds and detach from the terminal to become a daemon
    spinner -c '/path/to/app/script/process/spawner -p 9000 -i 10' -d # using custom spawner
  EOF

  opts.on("  Options:")

  opts.on("-c", "--command=path",    String) { |OPTIONS[:command]| }
  opts.on("-i", "--interval=seconds", Float) { |OPTIONS[:interval]| }
  opts.on("-d", "--daemon")                  { |OPTIONS[:daemon]| }

  opts.separator ""

  opts.on("-h", "--help", "Show this help message.") { puts opts; exit }

  opts.parse!
end

daemonize if OPTIONS[:daemon]

loop do
  system(OPTIONS[:command])
  sleep(OPTIONS[:interval])
end

trap(OPTIONS[:daemon] ? "TERM" : "INT") { exit }