about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-04-27 00:27:03 +0000
committerEric Wong <e@80x24.org>2016-04-27 00:29:51 +0000
commit40873caf4a71a56332d32e7f4086bf49ca6e3916 (patch)
tree366ca4e1eded899f6e625cb5173f9eacedb7ee6f
parent10aa29fa2c8fc4fdff8554eab24be07e6885aa50 (diff)
downloadyahns-40873caf4a71a56332d32e7f4086bf49ca6e3916.tar.gz
For slow clients, we want to be able to drop the connection
to the upstream as soon as we are done buffering and not waste
resources by leaving it in an :ignore state.  We also need to
remember the client for the fdmap to prevent shutdowns.

Ugh, this is really hard to test locally.
-rw-r--r--lib/yahns/proxy_http_response.rb29
1 files changed, 15 insertions, 14 deletions
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index e551323..3462e40 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -56,6 +56,7 @@ module Yahns::HttpResponse # :nodoc:
     :wait_readable # self remains in :ignore, wait on upstream
   end
 
+  # start streaming the response once upstream is done sending headers to us.
   # returns :wait_readable if we need to read more from req_res
   # returns :ignore if we yield control to the client(self)
   # returns nil if completely done
@@ -177,9 +178,9 @@ module Yahns::HttpResponse # :nodoc:
       end
     end
 
-    return proxy_busy_mod_done(alive) unless wbuf
-    req_res.resbuf = wbuf
-    proxy_busy_mod_blocked(wbuf, wbuf.busy)
+    # all done reading response from upstream, req_res will be discarded
+    # when we return nil:
+    wbuf ? proxy_busy_mod_blocked(wbuf, wbuf.busy) : proxy_busy_mod_done(alive)
   rescue => e
     proxy_err_response(502, req_res, e, wbuf)
   end
@@ -247,7 +248,7 @@ module Yahns::HttpResponse # :nodoc:
     end
 
     busy = wbuf.busy and return proxy_busy_mod_blocked(wbuf, busy)
-    proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil
+    proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil to close req_res
   end
 
   def proxy_wait_next(qflags)
@@ -288,23 +289,23 @@ module Yahns::HttpResponse # :nodoc:
     when :close then close
     end
 
-    nil # close the req_res, too
+    nil # signal close for ReqRes#yahns_step
   end
 
   def proxy_busy_mod_blocked(wbuf, busy)
-    q = Thread.current[:yahns_queue]
     # we are completely done reading and buffering the upstream response,
     # but have not completely written the response to the client,
     # yield control to the client socket:
     @state = wbuf
-    case busy
-    when :wait_readable then q.queue_mod(self, Yahns::Queue::QEV_RD)
-    when :wait_writable then q.queue_mod(self, Yahns::Queue::QEV_WR)
-    else
-      abort "BUG: invalid wbuf.busy: #{busy.inspect}"
-    end
-    # no touching self after queue_mod
-    :ignore
+    proxy_wait_next(case busy
+      when :wait_readable then Yahns::Queue::QEV_RD
+      when :wait_writable then Yahns::Queue::QEV_WR
+      else
+        abort "BUG: invalid wbuf.busy: #{busy.inspect}"
+      end)
+    # no touching self after proxy_wait_next, we may be running
+    # HttpClient#yahns_step in a different thread at this point
+    nil # signal close for ReqRes#yahns_step
   end
 
   # n.b.: we can use String#size for optimized dispatch under YARV instead