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.
Cluster only options that should not be passed in the command sent to the indiviual servers.
Maximum wait time for the server to be restarted
# File lib/thin/controllers/cluster.rb, line 28 28: def address; @options[:address] end
# File lib/thin/controllers/cluster.rb, line 27 27: def first_port; @options[:port] end
# File lib/thin/controllers/cluster.rb, line 31 31: def log_file; @options[:log] end
# File lib/thin/controllers/cluster.rb, line 123 123: def log_file_for(number) 124: include_server_number log_file, number 125: end
# File lib/thin/controllers/cluster.rb, line 34 34: def onebyone; @options[:onebyone] end
# File lib/thin/controllers/cluster.rb, line 33 33: def only; @options[:only] end
# File lib/thin/controllers/cluster.rb, line 30 30: def pid_file; @options[:pid] end
# File lib/thin/controllers/cluster.rb, line 127 127: def pid_file_for(number) 128: include_server_number pid_file, number 129: end
# File lib/thin/controllers/cluster.rb, line 135 135: def pid_for(number) 136: File.read(pid_file_for(number)).chomp.to_i 137: end
Stop and start the servers.
# File lib/thin/controllers/cluster.rb, line 66 66: def restart 67: unless onebyone 68: # Let's do a normal restart by defaults 69: stop 70: sleep 0.1 # Let's breath a bit shall we ? 71: start 72: else 73: with_each_server do |n| 74: stop_server(n) 75: sleep 0.1 # Let's breath a bit shall we ? 76: start_server(n) 77: wait_until_server_started(n) 78: end 79: end 80: end
# File lib/thin/controllers/cluster.rb, line 113 113: def server_id(number) 114: if socket 115: socket_for(number) 116: elsif swiftiply? 117: [address, first_port, number].join(':') 118: else 119: [address, number].join(':') 120: end 121: end
# File lib/thin/controllers/cluster.rb, line 32 32: def size; @options[:servers] end
# File lib/thin/controllers/cluster.rb, line 29 29: def socket; @options[:socket] end
# File lib/thin/controllers/cluster.rb, line 131 131: def socket_for(number) 132: include_server_number socket, number 133: end
Start the servers
# File lib/thin/controllers/cluster.rb, line 42 42: def start 43: with_each_server { |n| start_server n } 44: end
Start a single server
# File lib/thin/controllers/cluster.rb, line 47 47: def start_server(number) 48: log "Starting server on #{server_id(number)} ... " 49: 50: run :start, number 51: end
Stop the servers
# File lib/thin/controllers/cluster.rb, line 54 54: def stop 55: with_each_server { |n| stop_server n } 56: end
Stop a single server
# File lib/thin/controllers/cluster.rb, line 59 59: def stop_server(number) 60: log "Stopping server on #{server_id(number)} ... " 61: 62: run :stop, number 63: end
# File lib/thin/controllers/cluster.rb, line 37 37: def swiftiply? 38: @options.has_key?(:swiftiply) 39: end
# File lib/thin/controllers/cluster.rb, line 82 82: def test_socket(number) 83: if socket 84: UNIXSocket.new(socket_for(number)) 85: else 86: TCPSocket.new(address, number) 87: end 88: rescue 89: nil 90: end
# File lib/thin/controllers/cluster.rb, line 35 35: def wait; @options[:wait] end
Make sure the server is running before moving on to the next one.
# File lib/thin/controllers/cluster.rb, line 93 93: def wait_until_server_started(number) 94: log "Waiting for server to start ..." 95: STDOUT.flush # Need this to make sure user got the message 96: 97: tries = 0 98: loop do 99: if test_socket = test_socket(number) 100: test_socket.close 101: break 102: elsif tries < wait 103: sleep 1 104: tries += 1 105: else 106: raise RestartTimeout, "The server didn't start in time. Please look at server's log file " + 107: "for more information, or set the value of 'wait' in your config " + 108: "file to be higher (defaults: 30)." 109: end 110: end 111: end
Add the server port or number in the filename so each instance get its own file
# File lib/thin/controllers/cluster.rb, line 172 172: def include_server_number(path, number) 173: ext = File.extname(path) 174: path.gsub(/#{ext}$/, ".#{number}#{ext}") 175: end
Send the command to the thin script
# File lib/thin/controllers/cluster.rb, line 141 141: def run(cmd, number) 142: cmd_options = @options.reject { |option, value| CLUSTER_OPTIONS.include?(option) } 143: cmd_options.merge!(:pid => pid_file_for(number), :log => log_file_for(number)) 144: if socket 145: cmd_options.merge!(:socket => socket_for(number)) 146: elsif swiftiply? 147: cmd_options.merge!(:port => first_port) 148: else 149: cmd_options.merge!(:port => number) 150: end 151: Command.run(cmd, cmd_options) 152: end
# File lib/thin/controllers/cluster.rb, line 154 154: def with_each_server 155: if only 156: if first_port && only < 80 157: # interpret +only+ as a sequence number 158: yield first_port + only 159: else 160: # interpret +only+ as an absolute port number 161: yield only 162: end 163: elsif socket || swiftiply? 164: size.times { |n| yield n } 165: else 166: size.times { |n| yield first_port + n } 167: end 168: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.