class Thin::Controllers::Cluster
Control a set of servers.
-
Generate start and stop commands and run them.
-
Inject the port or socket number in the pid and log filenames.
Servers are started throught the thin
command-line script.
Constants
- CLUSTER_OPTIONS
Cluster only options that should not be passed in the command sent to the indiviual servers.
- DEFAULT_WAIT_TIME
Maximum wait time for the server to be restarted
Public Class Methods
new(options)
click to toggle source
Create a new cluster of servers launched using options
.
Calls superclass method
# File lib/thin/controllers/cluster.rb, line 21 def initialize(options) super # Cluster can only contain daemonized servers @options.merge!(:daemonize => true) end
Public Instance Methods
address()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 28 def address; @options[:address] end
first_port()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 27 def first_port; @options[:port] end
log_file()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 31 def log_file; @options[:log] end
log_file_for(number)
click to toggle source
# File lib/thin/controllers/cluster.rb, line 123 def log_file_for(number) include_server_number log_file, number end
onebyone()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 34 def onebyone; @options[:onebyone] end
only()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 33 def only; @options[:only] end
pid_file()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 30 def pid_file; @options[:pid] end
pid_file_for(number)
click to toggle source
# File lib/thin/controllers/cluster.rb, line 127 def pid_file_for(number) include_server_number pid_file, number end
pid_for(number)
click to toggle source
# File lib/thin/controllers/cluster.rb, line 135 def pid_for(number) File.read(pid_file_for(number)).chomp.to_i end
restart()
click to toggle source
Stop and start the servers.
# File lib/thin/controllers/cluster.rb, line 66 def restart unless onebyone # Let's do a normal restart by defaults stop sleep 0.1 # Let's breath a bit shall we ? start else with_each_server do |n| stop_server(n) sleep 0.1 # Let's breath a bit shall we ? start_server(n) wait_until_server_started(n) end end end
server_id(number)
click to toggle source
# File lib/thin/controllers/cluster.rb, line 113 def server_id(number) if socket socket_for(number) elsif swiftiply? [address, first_port, number].join(':') else [address, number].join(':') end end
size()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 32 def size; @options[:servers] end
socket()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 29 def socket; @options[:socket] end
socket_for(number)
click to toggle source
# File lib/thin/controllers/cluster.rb, line 131 def socket_for(number) include_server_number socket, number end
start()
click to toggle source
Start the servers
# File lib/thin/controllers/cluster.rb, line 42 def start with_each_server { |n| start_server n } end
start_server(number)
click to toggle source
Start a single server
# File lib/thin/controllers/cluster.rb, line 47 def start_server(number) log_info "Starting server on #{server_id(number)} ... " run :start, number end
stop()
click to toggle source
Stop the servers
# File lib/thin/controllers/cluster.rb, line 54 def stop with_each_server { |n| stop_server n } end
stop_server(number)
click to toggle source
Stop a single server
# File lib/thin/controllers/cluster.rb, line 59 def stop_server(number) log_info "Stopping server on #{server_id(number)} ... " run :stop, number end
swiftiply?()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 37 def swiftiply? @options.has_key?(:swiftiply) end
test_socket(number)
click to toggle source
# File lib/thin/controllers/cluster.rb, line 82 def test_socket(number) if socket UNIXSocket.new(socket_for(number)) else TCPSocket.new(address, number) end rescue nil end
wait()
click to toggle source
# File lib/thin/controllers/cluster.rb, line 35 def wait; @options[:wait] end
wait_until_server_started(number)
click to toggle source
Make sure the server is running before moving on to the next one.
# File lib/thin/controllers/cluster.rb, line 93 def wait_until_server_started(number) log_info "Waiting for server to start ..." STDOUT.flush # Need this to make sure user got the message tries = 0 loop do if test_socket = test_socket(number) test_socket.close break elsif tries < wait sleep 1 tries += 1 else raise RestartTimeout, "The server didn't start in time. Please look at server's log file " + "for more information, or set the value of 'wait' in your config " + "file to be higher (defaults: 30)." end end end
Private Instance Methods
include_server_number(path, number)
click to toggle source
Add the server port or number in the filename so each instance get its own file
# File lib/thin/controllers/cluster.rb, line 172 def include_server_number(path, number) ext = File.extname(path) path.gsub(/#{ext}$/, ".#{number}#{ext}") end
run(cmd, number)
click to toggle source
Send the command to the thin
script
# File lib/thin/controllers/cluster.rb, line 141 def run(cmd, number) cmd_options = @options.reject { |option, value| CLUSTER_OPTIONS.include?(option) } cmd_options.merge!(:pid => pid_file_for(number), :log => log_file_for(number)) if socket cmd_options.merge!(:socket => socket_for(number)) elsif swiftiply? cmd_options.merge!(:port => first_port) else cmd_options.merge!(:port => number) end Command.run(cmd, cmd_options) end
with_each_server() { |first_port| ... }
click to toggle source
# File lib/thin/controllers/cluster.rb, line 154 def with_each_server if only if first_port && only < 80 # interpret +only+ as a sequence number yield first_port + only else # interpret +only+ as an absolute port number yield only end elsif socket || swiftiply? size.times { |n| yield n } else size.times { |n| yield first_port + n } end end