cwsaylor (owner)

Revisions

gist: 17524 Download_button fork
public
Public Clone URL: git://gist.github.com/17524.git
Embed All Files: show embed
mongrel_cluster_god.rb #
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# run with: god -c /etc/god/mongrel_cluster_god.rb or use an init.d script
#
# This god script will monitor all of your mongrels that are setup with mongrel_cluster.
# It can monitor multiple apps if the mongrel cluster configs are symlinked into a central directory like /etc/mongrel_cluster/
# Mongrels are grouped by name which is derived from the mongrel_cluster symlink name
# i.e. /etc/mongrel_cluster/foo.conf
# I have those usually symlinked into the shared folder of the app
# group would be foo so you can control the group like this: god restart foo
 
require 'yaml'
 
MONGREL_CMD = "/usr/local/bin/mongrel_rails"
MONGREL_CLUSTER_ROOT = "/etc/mongrel_cluster"
MONGREL_USER = "vlad"
MONGREL_GROUP = "vlad"
MEMORY_LIMIT = 215 #MB
PROCESS_LIMIT = 50 #percent
 
#God::Contacts::Email.message_settings = {
# :from => 'admin@foo.com'
#}
 
#God::Contacts::Email.server_settings = {
# :address => 'localhost',
# :port => 25,
# :domain => 'foo.com'
#}
 
#God.contact(:email) do |c|
# c.name = 'Foo'
# c.email = 'admin@foo.com'
# c.group = 'developers'
#end
 
Dir[File.join(MONGREL_CLUSTER_ROOT, "*")].each do |config|
  next unless File.exist?(config)
  options = YAML.load_file(config)
  next if options["cwd"].nil? || options["pid_file"].nil? || options["servers"].nil? || options["port"].nil?
  app = File.basename(config).split(".").first
  pid_file_ext = File.extname(options["pid_file"])
  pid_file_base = File.basename(options["pid_file"], pid_file_ext)
  pid_file_dir = File.dirname(options["pid_file"])
 
  options["servers"].to_i.times do |i|
    port = options["port"].to_i + i
    God.watch do |w|
      w.name = "#{app}-mongrel-#{port}"
      w.group = app
      w.interval = 30.seconds # default
      w.start = "#{MONGREL_CMD} cluster::start -C #{File.expand_path(config)} --clean --only #{port}"
      w.stop = "#{MONGREL_CMD} cluster::stop -C #{File.expand_path(config)} --clean --only #{port}"
      w.start_grace = 10.seconds
      w.restart_grace = 10.seconds
      w.uid = MONGREL_USER
      w.gid = MONGREL_GROUP
      w.pid_file = File.join(options["cwd"], pid_file_dir, "#{pid_file_base}.#{port}#{pid_file_ext}")
 
      w.start_if do |start|
        start.condition(:process_running) do |c|
          c.interval = 5.seconds
          c.running = false
        end
      end
    
      w.restart_if do |restart|
        restart.condition(:memory_usage) do |c|
          c.above = MEMORY_LIMIT.to_i.megabytes
          c.times = [3, 5] # 3 out of 5 intervals
          #c.notify = 'developers'
        end
    
        restart.condition(:cpu_usage) do |c|
          c.above = PROCESS_LIMIT.to_i.percent
          c.times = 5
          #c.notify = 'developers'
        end
      end
    
      # lifecycle
      w.lifecycle do |on|
        on.condition(:flapping) do |c|
          c.to_state = [:start, :restart]
          c.times = 5
          c.within = 5.minute
          c.transition = :unmonitored
          c.retry_in = 10.minutes
          c.retry_times = 5
          c.retry_within = 2.hours
        end
      end
 
      #w.transition(:up, :start) do |on|
      # on.condition(:process_exits) do |c|
      # c.notify = 'developers'
      # end
      #end
 
    end # watch
  end # ports
  
end # configs