diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2015-10-25 19:05:43 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2015-10-25 19:05:43 +0900 |
commit | 7f176b380f88494123a4a51346ade28c4da51c00 (patch) | |
tree | 8293401abe3676d88e3236ea168c22137e79a63e /lib/plum/rack/server.rb | |
parent | 4dc76aeab391e29d0df33f58651ddc8232e262cb (diff) | |
parent | 7e998a7ae6826ebf2a50aa763b4d84f0082917ec (diff) | |
download | plum-7f176b380f88494123a4a51346ade28c4da51c00.tar.gz |
Merge remote-tracking branch 'plum-rack/master'
Diffstat (limited to 'lib/plum/rack/server.rb')
-rw-r--r-- | lib/plum/rack/server.rb | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/plum/rack/server.rb b/lib/plum/rack/server.rb new file mode 100644 index 0000000..a353db7 --- /dev/null +++ b/lib/plum/rack/server.rb @@ -0,0 +1,67 @@ +module Plum + module Rack + class Server + def initialize(app, config) + @state = :null + @app = config[:debug] ? ::Rack::CommonLogger.new(app) : app + @logger = Logger.new(config[:log] || $stdout).tap { |l| + l.level = config[:debug] ? Logger::DEBUG : Logger::INFO + } + @listeners = config[:listeners].map { |lc| + lc[:listener].new(lc) + } + + @logger.info("Plum #{::Plum::VERSION}") + @logger.info("Config: #{config}") + end + + def start + @state = :running + while @state == :running + break if @listeners.empty? + begin + if ss = IO.select(@listeners, nil, nil, 2.0) + ss[0].each { |svr| + new_con(svr) + } + end + rescue Errno::EBADF, Errno::ENOTSOCK, IOError => e # closed + rescue StandardError => e + @logger.error("#{e.class}: #{e.message}\n#{e.backtrace.map { |b| "\t#{b}" }.join("\n")}") + end + end + end + + def stop + @state = :stop + @listeners.map(&:stop) + # TODO: gracefully shutdown connections + end + + private + def new_con(svr) + sock = svr.accept + Thread.new { + begin + sock = sock.accept if sock.respond_to?(:accept) + plum = svr.plum(sock) + + #require "lineprof" + #Lineprof.profile(/plum/) { + con = Connection.new(@app, plum, @logger) + con.run + #} + rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINVAL => e # closed + sock.close if sock + rescue StandardError => e + @logger.error("#{e.class}: #{e.message}\n#{e.backtrace.map { |b| "\t#{b}" }.join("\n")}") + sock.close if sock + end + } + rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINVAL => e # closed + rescue StandardError => e + @logger.error("#{e.class}: #{e.message}\n#{e.backtrace.map { |b| "\t#{b}" }.join("\n")}") + end + end + end +end |