From 4d8304bf0aa5665e8f8474dfb96019297fa0c2b9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 25 Nov 2009 01:44:34 -0800 Subject: add FiberSpawn concurrency model This one seems a easy to get working and supports everything we need to support from the server perspective. Apps will need modified drivers, but it doesn't seem too hard to add more/better support for wrapping IO objects with Fiber::IO. --- lib/rainbows/fiber.rb | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 lib/rainbows/fiber.rb (limited to 'lib/rainbows/fiber.rb') diff --git a/lib/rainbows/fiber.rb b/lib/rainbows/fiber.rb new file mode 100644 index 0000000..e7d64ca --- /dev/null +++ b/lib/rainbows/fiber.rb @@ -0,0 +1,53 @@ +# -*- encoding: binary -*- +require 'fiber' +require 'rainbows/fiber/io' + +module Rainbows + module Fiber + RD = {} + WR = {} + + module Base + include Rainbows::Base + + def process_client(client) + G.cur += 1 + io = client.to_io + buf = client.read_timeout or return + hp = HttpParser.new + env = {} + alive = true + remote_addr = TCPSocket === io ? io.peeraddr.last : LOCALHOST + + begin # loop + while ! hp.headers(env, buf) + buf << client.read_timeout or return + end + + env[RACK_INPUT] = 0 == hp.content_length ? + HttpRequest::NULL_IO : TeeInput.new(client, env, hp, buf) + env[REMOTE_ADDR] = remote_addr + response = APP.call(env.update(RACK_DEFAULTS)) + + if 100 == response.first.to_i + client.write(EXPECT_100_RESPONSE) + env.delete(HTTP_EXPECT) + response = APP.call(env) + end + + alive = hp.keepalive? && G.alive + out = [ alive ? CONN_ALIVE : CONN_CLOSE ] if hp.headers? + HttpResponse.write(client, response, out) + end while alive and hp.reset.nil? and env.clear + io.close + rescue => e + handle_error(io, e) + ensure + G.cur -= 1 + RD.delete(client) + WR.delete(client) + end + + end + end +end -- cgit v1.2.3-24-ge0c7