lib/yarn/server.rb in yarn-0.1.0 vs lib/yarn/server.rb in yarn-0.1.1

- old
+ new

@@ -1,8 +1,10 @@ require 'socket' +# Yarn namespace module Yarn + # The heart of Yarn which starts a TCP server and forks workers which handles requests. class Server include Logging include Socket::Constants @@ -15,10 +17,11 @@ # set maximum number of ] attr_accessor :host, :port, :socket, :workers + # Initializes a new Server with the given options Hash. def initialize(options={}) # merge given options with default values opts = { output: $stdout, host: '127.0.0.1', @@ -26,30 +29,32 @@ workers: 4, log: true, rack: "off" }.merge(options) - @app = nil - @app = load_rack_app(opts[:rack]) unless opts[:rack] == "off" + @app = opts[:rack] == "off" ? nil : load_rack_app(opts[:rack]) @opts = opts @host, @port, @num_workers = opts[:host], opts[:port], opts[:workers] @workers = [] $output, $debug = opts[:output], opts[:debug] $log = opts[:log] || opts[:debug] end + # Loads a Rack application from a given file path. + # If the file does not exist, the program exits. def load_rack_app(app_path) if File.exists?(app_path) config_file = File.read(app_path) - rack_application = eval("Rack::Builder.new { #{config_file} }") + rack_application = eval("Rack::Builder.new { #{config_file} }.to_app", TOPLEVEL_BINDING, app_path) else log "#{app_path} does not exist. Exiting." Kernel::exit end end + # Creates a new TCPServer and invokes init_workers def start trap("INT") { stop } @socket = TCPServer.new(@host, @port) @socket.listen(1024) ::BasicSocket.do_not_reverse_lookup=true @@ -59,35 +64,43 @@ # Waits here for all processes to exit Process.waitall end + # Applies TCP optimizations to the TCP socket def configure_socket TCP_OPTS.each { |opt| @session.setsockopt(*opt) } end + # Runs fork_worker @num_worker times def init_workers @num_workers.times { @workers << fork_worker } end + # Forks a new process with a worker def fork_worker fork { worker } end + # Contains the logic performed by each worker. It first determines the + # handler type and then start an infinite loop listening for incomming + # requests. Upon receiving a request, it fires the run method on the handler. def worker trap("INT") { exit } handler = get_handler loop do @session = @socket.accept configure_socket handler.run @session end end + # Returns the handler corresponding to whether a Rack application is present. def get_handler @app ? RackHandler.new(@app,@opts) : RequestHandler.new end + # Closes the TCPServer and exits with a message. def stop @socket.close if (@socket && !@socket.closed?) log "Server stopped. Have a nice day!" end