Class: Rack::Cluster::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/cluster/runner.rb

Constant Summary collapse

DEFAULT_OPTIONS =
{
  :port => 3000,
  :environment => 'development',
  :servers => 1,
  :server => 'mongrel',
  :pid_file => 'tmp/pids/mongrel.pid',
  :verbose => false,
  :rackup => 'rackup'
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Runner

Returns a new instance of Runner.



16
17
18
19
# File 'lib/rack/cluster/runner.rb', line 16

def initialize(options = {})
  symbolized_options = Hash[options.map { |k, v| [k.to_sym, v] }]
  @options = DEFAULT_OPTIONS.merge(symbolized_options)
end

Class Method Details

.restart!(options = {}) ⇒ Object



29
30
31
# File 'lib/rack/cluster/runner.rb', line 29

def self.restart!(options = {})
  self.new(options).restart
end

.start!(options = {}) ⇒ Object



21
22
23
# File 'lib/rack/cluster/runner.rb', line 21

def self.start!(options = {})
  self.new(options).start
end

.stop!(options = {}) ⇒ Object



25
26
27
# File 'lib/rack/cluster/runner.rb', line 25

def self.stop!(options = {})
  self.new(options).stop
end

Instance Method Details

#config_ruObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rack/cluster/runner.rb', line 83

def config_ru
  config_ru_file = @options[:config_ru]
  config_ru_absolute_path = config_ru_file =~ /^\//
  cwd = @options[:cwd]

  if config_ru_file && cwd
    if config_ru_absolute_path
      config_ru_file
    else
      File.join(cwd, config_ru_file)
    end
  elsif config_ru_file
    config_ru_file
  elsif cwd
    File.join(cwd, 'config.ru')
  else
    'config.ru'
  end
end

#end_portObject



111
112
113
# File 'lib/rack/cluster/runner.rb', line 111

def end_port
  start_port + (servers - 1)
end

#pid_file_for_port(port) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/rack/cluster/runner.rb', line 115

def pid_file_for_port(port)
  return unless @options[:pid_file]

  pid_file_dir = File.dirname(@options[:pid_file])
  pid_file_ext = File.extname(@options[:pid_file])
  pid_file_basename = File.basename(@options[:pid_file], pid_file_ext)
  
  full_pid_file_dir = if @options[:cwd]
                        File.join(@options[:cwd], pid_file_dir)
                      else
                        pid_file_dir
                      end

  File.join(full_pid_file_dir, "#{pid_file_basename}.#{port}#{pid_file_ext}")
end

#pid_file_for_port_exists?(port) ⇒ Boolean

Returns:

  • (Boolean)


131
132
133
134
# File 'lib/rack/cluster/runner.rb', line 131

def pid_file_for_port_exists?(port)
  return false unless @options[:pid_file]
  File.exists?(pid_file_for_port(port))
end

#restartObject



78
79
80
81
# File 'lib/rack/cluster/runner.rb', line 78

def restart
  stop
  start
end

#running_on_port?(port) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
139
140
141
142
143
144
# File 'lib/rack/cluster/runner.rb', line 136

def running_on_port?(port)
  return false unless pid_file_for_port_exists?(port)

  pid = File.read(pid_file_for_port(port)).to_i
  processes = `ps -p #{pid} -o cmd=`
  
  return true if processes =~ /rackup/
  false
end

#serversObject



103
104
105
# File 'lib/rack/cluster/runner.rb', line 103

def servers
  @options[:servers].to_i != 0 ? @options[:servers].to_i : 1
end

#startObject



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
# File 'lib/rack/cluster/runner.rb', line 33

def start
  start_port.upto(end_port) do |port|
    if pid_file_for_port_exists?(port) && running_on_port?(port)
      puts "already running on port #{port}"
      next
    end

    if pid_file_for_port_exists?(port) && !running_on_port?(port)
      puts "cleaning up pid file for port #{port}"
      File.unlink(pid_file_for_port(port))
    end

    cmd = "#{@options[:rackup]} -D"
    cmd << " -s #{@options[:server]}"
    cmd << " -E #{@options[:environment]}"
    cmd << " -p #{port}"
    cmd << " -P #{pid_file_for_port(port)}"
    cmd << " #{config_ru}" if config_ru
    
    puts "starting port #{port}"
    puts "#{cmd}" if verbose
    output = `#{cmd}`
    STDERR.puts(output) unless $?.success?
  end
end

#start_portObject



107
108
109
# File 'lib/rack/cluster/runner.rb', line 107

def start_port
  @options[:port].to_i
end

#stopObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rack/cluster/runner.rb', line 59

def stop
  start_port.upto(end_port) do |port|
    if pid_file_for_port_exists?(port) && !running_on_port?(port)
      puts "cleaning up pid file for port #{port}"
      File.unlink(pid_file_for_port(port))
    end

    unless running_on_port?(port)
      puts "no process to stop on port #{port}"
      next
    end

    pid = File.read(pid_file_for_port(port)).to_i

    puts "killing #{port}, pid #{pid}"
    Process.kill("KILL", pid)
  end
end

#verboseObject



146
147
148
# File 'lib/rack/cluster/runner.rb', line 146

def verbose
  @options[:verbose]
end