about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-10-25 16:34:33 -0700
committerEric Wong <normalperson@yhbt.net>2009-10-26 02:26:22 -0700
commitfa93a16ede574df6159497a526153a9978b66dd1 (patch)
tree7df4902849493bdf7a5547153e4c5934cbef9b13
parent8487d928f9581d98aee14e1991f129422278367c (diff)
downloadrainbows-fa93a16ede574df6159497a526153a9978b66dd1.tar.gz
log reopens, graceful shutdown, HTTP error responses
should all be working now.
-rw-r--r--lib/rainbows/event_machine.rb22
-rw-r--r--t/GNUmakefile5
-rw-r--r--t/simple-http_EventMachine.ru9
3 files changed, 32 insertions, 4 deletions
diff --git a/lib/rainbows/event_machine.rb b/lib/rainbows/event_machine.rb
index 2cc0f15..176bf51 100644
--- a/lib/rainbows/event_machine.rb
+++ b/lib/rainbows/event_machine.rb
@@ -37,6 +37,11 @@ module Rainbows
       alias write send_data
       alias receive_data on_read
 
+      def quit
+        super
+        close_connection_after_writing
+      end
+
       def app_call
         begin
           (@env[RACK_INPUT] = @input).rewind
@@ -54,7 +59,7 @@ module Rainbows
             # keepalive requests are always body-less, so @input is unchanged
             @hp.headers(@env, @buf) and next
           else
-            @state = :close
+            quit
           end
           return
         end while true
@@ -89,6 +94,11 @@ module Rainbows
         @em_conns = conns
       end
 
+      def close
+        detach
+        @l.close
+      end
+
       def notify_readable
         return if @em_conns.size >= @limit
         begin
@@ -109,8 +119,14 @@ module Rainbows
       EM.run {
         conns = EM.instance_variable_get(:@conns) or
           raise RuntimeError, "EM @conns instance variable not accessible!"
-        EM.add_periodic_timer(1) { worker.tmp.chmod(m = 0 == m ? 1 : 0) }
-        LISTENERS.each { |s| EM.attach(s, Server, s, conns) }
+        EM.add_periodic_timer(1) do
+          worker.tmp.chmod(m = 0 == m ? 1 : 0)
+          unless G.alive
+            conns.each_value { |client| Client === client and client.quit }
+            EM.stop if conns.empty? && EM.reactor_running?
+          end
+        end
+        LISTENERS.map! { |s| EM.attach(s, Server, s, conns) }
       }
     end
 
diff --git a/t/GNUmakefile b/t/GNUmakefile
index 465a68b..4fcbc81 100644
--- a/t/GNUmakefile
+++ b/t/GNUmakefile
@@ -17,7 +17,7 @@ endif
 export RUBYLIB RUBY_VERSION
 
 models := ThreadPool ThreadSpawn Revactor Rev
-all_models := $(models) Base
+all_models := $(models) Base EventMachine
 
 T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
 
@@ -26,6 +26,9 @@ $(T): MODELS = $(models)
 
 # some tests can be run with all models
 t0000-simple-http.sh: MODELS = $(all_models)
+t0002-graceful.sh: MODELS = $(all_models)
+t0002-parser-error.sh: MODELS = $(all_models)
+t0003-reopen-logs.sh: MODELS = $(all_models)
 
 # this test is not compatible with non-Thread models yet
 t9000-rack-app-pool.sh: MODELS = ThreadPool ThreadSpawn
diff --git a/t/simple-http_EventMachine.ru b/t/simple-http_EventMachine.ru
new file mode 100644
index 0000000..192b908
--- /dev/null
+++ b/t/simple-http_EventMachine.ru
@@ -0,0 +1,9 @@
+use Rack::ContentLength
+use Rack::ContentType
+run lambda { |env|
+  if env['rack.multithread'] == false && env['rainbows.model'] == :EventMachine
+    [ 200, {}, [ env.inspect << "\n" ] ]
+  else
+    raise "rack.multithread is true"
+  end
+}