aboutsummaryrefslogtreecommitdiffstats
path: root/lib/plum/rack/server.rb
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2015-10-25 19:05:43 +0900
committerKazuki Yamaguchi <k@rhe.jp>2015-10-25 19:05:43 +0900
commit7f176b380f88494123a4a51346ade28c4da51c00 (patch)
tree8293401abe3676d88e3236ea168c22137e79a63e /lib/plum/rack/server.rb
parent4dc76aeab391e29d0df33f58651ddc8232e262cb (diff)
parent7e998a7ae6826ebf2a50aa763b4d84f0082917ec (diff)
downloadplum-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.rb67
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