flowerbox-delivery/lib/flowerbox/delivery/server.rb

126 lines
2.6 KiB
Ruby
Raw Normal View History

require 'rack'
require 'net/http'
require 'socket'
2012-03-14 17:07:28 +00:00
require 'rack/builder'
2012-03-14 21:41:02 +00:00
require 'thin'
module Flowerbox
module Delivery
class Server
attr_reader :options
def initialize(options = {})
2012-03-02 18:29:15 +00:00
@options = { :logging => false }.merge(options || {})
end
def start
@server_thread = Thread.new do
2012-03-02 18:29:15 +00:00
server_options = { :Port => port, :Host => interface }
2012-03-14 17:07:28 +00:00
app = options[:app]
2012-03-14 21:41:02 +00:00
Thin::Logging.silent = !options[:logging]
2012-03-14 17:07:28 +00:00
if options[:logging]
real_app = app
app = ::Rack::Builder.new do
use ::Rack::CommonLogger, STDOUT
run real_app
end
2012-03-02 18:29:15 +00:00
end
2012-03-14 17:07:28 +00:00
::Rack::Handler::Thin.run(app, server_options) do |server|
Thread.current[:server] = server
trap('QUIT') { server.stop }
2012-02-29 19:24:07 +00:00
end
end
2012-02-29 19:24:07 +00:00
while !@server_thread[:server] && @server_thread.alive?
sleep 0.1
end
2012-02-29 19:24:07 +00:00
raise StandardError.new("Server died") if !@server_thread[:server].running?
end
def stop
if @server_thread
2012-03-14 17:07:28 +00:00
@server_thread[:server].stop
wait_for_server_to_stop
end
end
def interface
options[:interface] || '0.0.0.0'
end
def port
return @port if @port ||= options[:port]
attempts = 20
begin
attempts -= 1
current_port = random_port
begin
socket = TCPSocket.new(interface, current_port)
socket.close
rescue Errno::ECONNREFUSED => e
@port = current_port
end
end while !@port and attempts > 0
raise StandardError.new("can't start server") if attempts == 0
@port
end
2012-03-14 17:07:28 +00:00
def address
"http://#{interface}:#{port}/"
end
def alive?
@server_thread.alive?
end
private
def wait_for_server_to_start
while true do
begin
connect_interface = '127.0.0.1' if interface == '0.0.0.0'
TCPSocket.new(connect_interface, port)
break
rescue Errno::ECONNREFUSED => e
end
sleep 0.1
end
end
def wait_for_server_to_stop
2012-03-14 17:07:28 +00:00
while alive? do
begin
connect_interface = '127.0.0.1' if interface == '0.0.0.0'
socket = TCPSocket.new(connect_interface, port)
socket.close
rescue Errno::ECONNREFUSED => e
return
end
sleep 0.1
end
end
def random_port
25000 + Kernel.rand(1000)
end
end
end
end