Class: Yarn::Server
- Inherits:
-
Object
- Object
- Yarn::Server
- Includes:
- Socket::Constants, Logging
- Defined in:
- lib/yarn/server.rb
Overview
The heart of Yarn which starts a TCP server and forks workers which handles requests.
Constant Summary collapse
- TCP_OPTS =
TCP optimizations
[ # delays accepting connections until clients send data [Socket::SOL_TCP, TCP_DEFER_ACCEPT, 1], # send ACK flags in their own packets (faster) [Socket::SOL_TCP, TCP_QUICKACK, 1], # set maximum number of ]
Instance Attribute Summary collapse
-
#host ⇒ Object
Returns the value of attribute host.
-
#port ⇒ Object
Returns the value of attribute port.
-
#socket ⇒ Object
Returns the value of attribute socket.
-
#workers ⇒ Object
Returns the value of attribute workers.
Instance Method Summary collapse
-
#configure_socket ⇒ Object
Applies TCP optimizations to the TCP socket.
-
#fork_worker ⇒ Object
Forks a new process with a worker.
-
#get_handler ⇒ Object
Returns the handler corresponding to whether a Rack application is present.
-
#init_workers ⇒ Object
Runs fork_worker @num_worker times.
-
#initialize(options = {}) ⇒ Server
constructor
Initializes a new Server with the given options Hash.
-
#load_rack_app(app_path) ⇒ Object
Loads a Rack application from a given file path.
-
#start ⇒ Object
Creates a new TCPServer and invokes init_workers.
-
#stop ⇒ Object
Closes the TCPServer and exits with a message.
-
#worker ⇒ Object
Contains the logic performed by each worker.
Methods included from Logging
#debug, #log, #output, #timestamp
Constructor Details
#initialize(options = {}) ⇒ Server
Initializes a new Server with the given options Hash.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/yarn/server.rb', line 23 def initialize(={}) # merge given options with default values opts = { output: $stdout, host: '127.0.0.1', port: 3000, workers: 4, log: true, rack: "off" }.merge() @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 |
Instance Attribute Details
#host ⇒ Object
Returns the value of attribute host.
20 21 22 |
# File 'lib/yarn/server.rb', line 20 def host @host end |
#port ⇒ Object
Returns the value of attribute port.
20 21 22 |
# File 'lib/yarn/server.rb', line 20 def port @port end |
#socket ⇒ Object
Returns the value of attribute socket.
20 21 22 |
# File 'lib/yarn/server.rb', line 20 def socket @socket end |
#workers ⇒ Object
Returns the value of attribute workers.
20 21 22 |
# File 'lib/yarn/server.rb', line 20 def workers @workers end |
Instance Method Details
#configure_socket ⇒ Object
Applies TCP optimizations to the TCP socket
70 71 72 |
# File 'lib/yarn/server.rb', line 70 def configure_socket TCP_OPTS.each { |opt| @session.setsockopt(*opt) } end |
#fork_worker ⇒ Object
Forks a new process with a worker
80 81 82 |
# File 'lib/yarn/server.rb', line 80 def fork_worker fork { worker } end |
#get_handler ⇒ Object
Returns the handler corresponding to whether a Rack application is present.
98 99 100 |
# File 'lib/yarn/server.rb', line 98 def get_handler @app ? RackHandler.new(@app,@opts) : RequestHandler.new end |
#init_workers ⇒ Object
Runs fork_worker @num_worker times
75 76 77 |
# File 'lib/yarn/server.rb', line 75 def init_workers @num_workers.times { @workers << fork_worker } end |
#load_rack_app(app_path) ⇒ Object
Loads a Rack application from a given file path. If the file does not exist, the program exits.
45 46 47 48 49 50 51 52 53 |
# File 'lib/yarn/server.rb', line 45 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} }.to_app", TOPLEVEL_BINDING, app_path) else log "#{app_path} does not exist. Exiting." Kernel::exit end end |
#start ⇒ Object
Creates a new TCPServer and invokes init_workers
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/yarn/server.rb', line 56 def start trap("INT") { stop } @socket = TCPServer.new(@host, @port) @socket.listen(1024) ::BasicSocket.do_not_reverse_lookup=true log "Yarn started #{@num_workers} workers and is listening on #{@host}:#{@port}" init_workers # Waits here for all processes to exit Process.waitall end |
#stop ⇒ Object
Closes the TCPServer and exits with a message.
103 104 105 106 107 |
# File 'lib/yarn/server.rb', line 103 def stop @socket.close if (@socket && !@socket.closed?) log "Server stopped. Have a nice day!" end |
#worker ⇒ Object
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.
87 88 89 90 91 92 93 94 95 |
# File 'lib/yarn/server.rb', line 87 def worker trap("INT") { exit } handler = get_handler loop do @session = @socket.accept configure_socket handler.run @session end end |