From 77f930cb64d32b3fac942b462cf4c7a04af730e3 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 18 Nov 2009 00:08:52 -0800 Subject: make keepalive_timeout configurable And change the default to 2 seconds, most clients can render the page and load all URLs within 2 seconds. --- lib/rainbows.rb | 11 +++++++++-- lib/rainbows/base.rb | 2 +- lib/rainbows/event_machine.rb | 2 +- lib/rainbows/http_server.rb | 5 +++++ lib/rainbows/rev/heartbeat.rb | 6 ++++-- lib/rainbows/revactor.rb | 3 ++- 6 files changed, 22 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/rainbows.rb b/lib/rainbows.rb index 4686f2b..3fed331 100644 --- a/lib/rainbows.rb +++ b/lib/rainbows.rb @@ -6,7 +6,7 @@ module Rainbows # global vars because class/instance variables are confusing me :< # this struct is only accessed inside workers and thus private to each # G.cur may not be used the network concurrency model - class State < Struct.new(:alive,:m,:cur,:server,:tmp) + class State < Struct.new(:alive,:m,:cur,:kato,:server,:tmp) def tick tmp.chmod(self.m = m == 0 ? 1 : 0) alive && server.master_pid == Process.ppid or quit! @@ -18,7 +18,7 @@ module Rainbows false end end - G = State.new(true, 0, 0) + G = State.new(true, 0, 0, 2) require 'rainbows/const' require 'rainbows/http_server' @@ -43,6 +43,7 @@ module Rainbows # Rainbows! do # use :Revactor # this may also be :ThreadSpawn or :ThreadPool # worker_connections 400 + # keepalive_timeout 0 # zero disables keepalives entirely # end # # # the rest of the Unicorn configuration @@ -53,6 +54,12 @@ module Rainbows # each of them. The total number of clients we're able to serve is # +worker_processes+ * +worker_connections+, so in the above example # we can serve 8 * 400 = 3200 clients concurrently. + # + # The default is +keepalive_timeout+ is 2 seconds, which should be + # enough under most conditions for browsers to render the page and + # start retrieving extra elements for. Increasing this beyond 5 + # seconds is not recommended. Zero disables keepalive entirely + # (but pipelining fully-formed requests is still works). def Rainbows!(&block) block_given? or raise ArgumentError, "Rainbows! requires a block" HttpServer.setup(block) diff --git a/lib/rainbows/base.rb b/lib/rainbows/base.rb index 62a7701..9a653ff 100644 --- a/lib/rainbows/base.rb +++ b/lib/rainbows/base.rb @@ -40,7 +40,7 @@ module Rainbows begin # loop while ! hp.headers(env, buf) - IO.select([client], nil, nil, 5) or return client.close + IO.select([client], nil, nil, G.kato) or return client.close buf << client.readpartial(CHUNK_SIZE) end diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb index 056bdd5..54c1bc0 100644 --- a/lib/rainbows/event_machine.rb +++ b/lib/rainbows/event_machine.rb @@ -74,7 +74,7 @@ module Rainbows @state = :headers # keepalive requests are always body-less, so @input is unchanged @hp.headers(@env, @buf) and next - set_comm_inactivity_timeout 5 + set_comm_inactivity_timeout G.kato end return end while true diff --git a/lib/rainbows/http_server.rb b/lib/rainbows/http_server.rb index c26285c..da97929 100644 --- a/lib/rainbows/http_server.rb +++ b/lib/rainbows/http_server.rb @@ -68,6 +68,11 @@ module Rainbows @worker_connections = nr end + def keepalive_timeout(nr) + (Integer === nr && nr >= 0) or + raise ArgumentError, "keepalive must be a non-negative Integer" + G.kato = nr + end end end diff --git a/lib/rainbows/rev/heartbeat.rb b/lib/rainbows/rev/heartbeat.rb index 5f76ed7..ee9d1b5 100644 --- a/lib/rainbows/rev/heartbeat.rb +++ b/lib/rainbows/rev/heartbeat.rb @@ -10,8 +10,10 @@ module Rainbows class Heartbeat < ::Rev::TimerWatcher def on_timer - ot = Time.now - 5 - KATO.delete_if { |client, time| time < ot and client.timeout? } + if (ot = G.kato) > 0 + ot = Time.now - ot + KATO.delete_if { |client, time| time < ot and client.timeout? } + end exit if (! G.tick && G.cur <= 0) end diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb index 4cf6f11..489236c 100644 --- a/lib/rainbows/revactor.rb +++ b/lib/rainbows/revactor.rb @@ -23,7 +23,7 @@ module Rainbows module Revactor require 'rainbows/revactor/tee_input' - RD_ARGS = { :timeout => 5 } + RD_ARGS = {} include Base @@ -75,6 +75,7 @@ module Rainbows # given a INT, QUIT, or TERM signal) def worker_loop(worker) init_worker_process(worker) + RD_ARGS[:timeout] = G.kato if G.kato > 0 root = Actor.current root.trap_exit = true -- cgit v1.2.3-24-ge0c7