* [WIP] rely on optimized case dispatch
@ 2015-12-04 22:49 Eric Wong
2015-12-08 5:19 ` [WIP v2] " Eric Wong
0 siblings, 1 reply; 2+ messages in thread
From: Eric Wong @ 2015-12-04 22:49 UTC (permalink / raw)
To: yahns-public
In the future, Ruby may optimize case dispatch for additional
immediate values such as `nil', `true', and `false'.
Rearrange our case statements (and take away some safety-checks
:x) to take advantage of these (to-be-done) optimizations.
Note: totally untested at the moment and the changes to
Ruby have not yet landed.
ref:
https://bugs.ruby-lang.org/issues/11769
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/71818
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/71825
---
| 2 +-
lib/yahns/http_client.rb | 28 +++++++++++-----------
lib/yahns/http_response.rb | 26 ++++++++++-----------
lib/yahns/proxy_http_response.rb | 50 ++++++++++++++++++++--------------------
lib/yahns/sendfile_compat.rb | 6 ++---
lib/yahns/wbuf.rb | 4 ++--
lib/yahns/wbuf_str.rb | 4 ++--
lib/yahns/worker.rb | 10 ++++----
8 files changed, 64 insertions(+), 66 deletions(-)
--git a/extras/proxy_pass.rb b/extras/proxy_pass.rb
index 29dd995..bfe3b8f 100644
--- a/extras/proxy_pass.rb
+++ b/extras/proxy_pass.rb
@@ -61,7 +61,7 @@ class ProxyPass # :nodoc:
kgio_wait_writable(wait_time)
when nil
return
- when String
+ else # String
buf = rv
end while true
end
diff --git a/lib/yahns/http_client.rb b/lib/yahns/http_client.rb
index db53587..72cc8b4 100644
--- a/lib/yahns/http_client.rb
+++ b/lib/yahns/http_client.rb
@@ -28,15 +28,13 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
when :ignore # :ignore on hijack
@state = :ignore
return :ignore
- when Yahns::StreamFile
- @state = rv # continue looping
when true, false # done
return http_response_done(rv)
when :ccc_done, :r100_done
@state = rv
return :wait_writable
- else
- raise "BUG: #{@state.inspect}#wbuf_flush returned #{rv.inspect}"
+ else # Yahns::StreamFile
+ @state = rv # continue looping
end while true
end
@@ -79,14 +77,14 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
# returns :wait_readable/wait_writable/nil to yield back to epoll
def fill_body(rsize, rbuf)
case rv = kgio_tryread(rsize, rbuf)
- when String
- @hs.filter_body(rbuf, @hs.buf << rbuf)
- @input.write(rbuf)
- true # keep looping on kgio_tryread (but check body_eof? first)
when :wait_readable, :wait_writable
rv # have epoll/kqueue wait for more
when nil # unexpected EOF
@input.close # nil
+ else # String
+ @hs.filter_body(rbuf, @hs.buf << rbuf)
+ @input.write(rbuf)
+ true # keep looping on kgio_tryread (but check body_eof? first)
end
end
@@ -94,16 +92,16 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
# returns :wait_readable/wait_writable/nil to yield back to epoll
def read_trailers(rsize, rbuf)
case rv = kgio_tryread(rsize, rbuf)
- when String
+ when :wait_readable, :wait_writable
+ return rv # wait for more
+ when nil # unexpected EOF
+ return @input.close # nil
+ else # String
if @hs.add_parse(rbuf)
@input.rewind
return true
end
# keep looping on kgio_tryread...
- when :wait_readable, :wait_writable
- return rv # wait for more
- when nil # unexpected EOF
- return @input.close # nil
end while true
end
@@ -234,12 +232,12 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc:
# used by StreamInput (and thus TeeInput) for input_buffering {false|:lazy}
def yahns_read(bytes, buf)
case rv = kgio_tryread(bytes, buf)
- when String, nil
- return rv
when :wait_readable
kgio_wait_readable or raise Yahns::ClientTimeout, "waiting for read", []
when :wait_writable
kgio_wait_writable or raise Yahns::ClientTimeout, "waiting for write", []
+ else # String, nil
+ return rv
end while true
end
diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb
index 99bf664..cbfcf77 100644
--- a/lib/yahns/http_response.rb
+++ b/lib/yahns/http_response.rb
@@ -75,11 +75,11 @@ module Yahns::HttpResponse # :nodoc:
case rv = wbuf.wbuf_close(self)
when :ignore # hijacked
@state = rv
- when Yahns::StreamFile
- @state = rv
- :wait_writable
when true, false
http_response_done(rv)
+ else # Yahns::StreamFile
+ @state = rv
+ :wait_writable
end
else
@state = wbuf
@@ -162,9 +162,6 @@ module Yahns::HttpResponse # :nodoc:
case rv = kgio_syssend(buf, flags)
when nil # all done, likely
break
- when String
- flags = MSG_DONTWAIT
- buf = rv # hope the skb grows
when :wait_writable, :wait_readable
if k.output_buffering
alive = hijack ? hijack : alive
@@ -174,6 +171,9 @@ module Yahns::HttpResponse # :nodoc:
else
response_wait_write(rv) or return :close
end
+ else # String
+ flags = MSG_DONTWAIT
+ buf = rv # hope the skb grows
end while true
end
@@ -192,8 +192,6 @@ module Yahns::HttpResponse # :nodoc:
case rv = kgio_trywrite(chunk)
when nil # all done, likely and good!
break
- when String
- chunk = rv # hope the skb grows when we loop into the trywrite
when :wait_writable, :wait_readable
if k.output_buffering
wbuf = Yahns::Wbuf.new(body, alive, k.output_buffer_tmpdir, rv)
@@ -202,6 +200,8 @@ module Yahns::HttpResponse # :nodoc:
else
response_wait_write(rv) or return :close
end
+ else # String
+ chunk = rv # hope the skb grows when we loop into the trywrite
end while true
end
end
@@ -231,8 +231,6 @@ module Yahns::HttpResponse # :nodoc:
case rv = kgio_trywrite(buf)
when nil
break
- when String
- buf = rv
when :wait_writable, :wait_readable
if self.class.output_buffering
wbuf = buf.dup
@@ -241,6 +239,8 @@ module Yahns::HttpResponse # :nodoc:
else
response_wait_write(rv) or return :close
end
+ else # String
+ buf = rv
end while true
end
end
@@ -257,8 +257,6 @@ module Yahns::HttpResponse # :nodoc:
: "HTTP/1.1 100 Continue\r\n\r\n".freeze
case rv = kgio_trywrite(buf)
- when String
- buf = rv
when :wait_writable, :wait_readable
if self.class.output_buffering
@state = Yahns::WbufStr.new(buf, :r100_done)
@@ -266,8 +264,10 @@ module Yahns::HttpResponse # :nodoc:
else
response_wait_write(rv) or return :close
end
- else
+ when nil
return rv
+ else # String
+ buf = rv
end while true
end
end
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index 3858456..13f8870 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -13,12 +13,12 @@ module Yahns::HttpResponse # :nodoc:
# no write buffer, try to write directly to the client socket
case rv = String === buf ? kgio_trywrite(buf) : kgio_trywritev(buf)
when nil then return # done writing buf, likely
- when String, Array # partial write, hope the skb grows
- buf = rv
when :wait_writable, :wait_readable
wbuf = Yahns::Wbuf.new(nil, alive, self.class.output_buffer_tmpdir, rv)
buf = buf.join if Array === buf
break
+ else # String, Array # partial write, hope the skb grows
+ buf = rv
end while true
end
@@ -97,12 +97,12 @@ module Yahns::HttpResponse # :nodoc:
# send the headers
case rv = kgio_syssend(res, flags)
when nil then break # all done, likely
- when String # partial write, highly unlikely
- flags = MSG_DONTWAIT
- res = rv # hope the skb grows
when :wait_writable, :wait_readable # highly unlikely in real apps
wbuf = proxy_write(nil, res, alive)
break # keep buffering as much as possible
+ else # String # partial write, highly unlikely
+ flags = MSG_DONTWAIT
+ res = rv # hope the skb grows
end while true
rbuf = Thread.current[:yahns_rbuf]
@@ -112,26 +112,26 @@ module Yahns::HttpResponse # :nodoc:
if len = kcar.body_bytes_left
case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
- when String
- len = kcar.body_bytes_left -= tmp.size
- wbuf = proxy_write(wbuf, tmp, alive)
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
+ else # String
+ len = kcar.body_bytes_left -= tmp.size
+ wbuf = proxy_write(wbuf, tmp, alive)
end until len == 0
elsif kcar.chunked? # nasty chunked body
req_res.proxy_trailers = nil # define to avoid warnings for now
buf = ''
case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
- when String
- kcar.filter_body(buf, tmp)
- wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty?
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
+ else # String
+ kcar.filter_body(buf, tmp)
+ wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty?
end until kcar.body_eof?
buf = tmp
@@ -139,12 +139,12 @@ module Yahns::HttpResponse # :nodoc:
rbuf = Thread.current[:yahns_rbuf] = ''
until kcar.trailers(tlr, buf)
case rv = req_res.kgio_tryread(0x2000, rbuf)
- when String
- buf << rv
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
+ else # String
+ buf << rv
end # no loop here
end
wbuf = proxy_write(wbuf, trailer_out(tlr), alive)
@@ -152,13 +152,13 @@ module Yahns::HttpResponse # :nodoc:
else # no Content-Length or Transfer-Encoding: chunked, wait on EOF!
case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
- when String
- wbuf = proxy_write(wbuf, tmp, alive)
when nil
req_res.shutdown
break
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
+ else # String
+ wbuf = proxy_write(wbuf, tmp, alive)
end while true
end
@@ -176,13 +176,13 @@ module Yahns::HttpResponse # :nodoc:
if len = kcar.body_bytes_left
case tmp = req_res.kgio_tryread(0x2000, rbuf)
- when String
- len = kcar.body_bytes_left -= tmp.size
- wbuf.wbuf_write(self, tmp)
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return :wait_readable # self remains in :ignore, wait on upstream
+ else # String
+ len = kcar.body_bytes_left -= tmp.size
+ wbuf.wbuf_write(self, tmp)
end while len != 0
elsif kcar.chunked? # nasty chunked body
@@ -191,13 +191,13 @@ module Yahns::HttpResponse # :nodoc:
unless req_res.proxy_trailers
# are we done dechunking the main body, yet?
case tmp = req_res.kgio_tryread(0x2000, rbuf)
- when String
- kcar.filter_body(buf, tmp)
- buf.empty? or wbuf.wbuf_write(self, chunk_out(buf))
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return :wait_readable # self remains in :ignore, wait on upstream
+ else # String
+ kcar.filter_body(buf, tmp)
+ buf.empty? or wbuf.wbuf_write(self, chunk_out(buf))
end until kcar.body_eof?
req_res.proxy_trailers = [ tmp, [] ] # onto trailers!
rbuf = Thread.current[:yahns_rbuf] = ''
@@ -206,12 +206,12 @@ module Yahns::HttpResponse # :nodoc:
buf, tlr = *req_res.proxy_trailers
until kcar.trailers(tlr, buf)
case rv = req_res.kgio_tryread(0x2000, rbuf)
- when String
- buf << rv
when :wait_readable
return :wait_readable
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
+ else # String
+ buf << rv
end # no loop here
end
wbuf.wbuf_write(self, trailer_out(tlr))
@@ -219,13 +219,13 @@ module Yahns::HttpResponse # :nodoc:
else # no Content-Length or Transfer-Encoding: chunked, wait on EOF!
case tmp = req_res.kgio_tryread(0x2000, rbuf)
- when String
- wbuf.wbuf_write(self, tmp)
when nil
req_res.shutdown
break
when :wait_readable
return :wait_readable # self remains in :ignore, wait on upstream
+ else # String
+ wbuf.wbuf_write(self, tmp)
end while true
end
diff --git a/lib/yahns/sendfile_compat.rb b/lib/yahns/sendfile_compat.rb
index da2a9ec..6d4cc56 100644
--- a/lib/yahns/sendfile_compat.rb
+++ b/lib/yahns/sendfile_compat.rb
@@ -11,13 +11,13 @@ module Yahns::SendfileCompat
str = io.read(count, buf) or return # nil for EOF
n = 0
case rv = kgio_trywrite(str)
- when String # partial write, keep trying
- n += (str.size - rv.size)
- str = rv
when :wait_writable, :wait_readable
return n > 0 ? n : rv
when nil
return n + str.size # yay!
+ else # String # partial write, keep trying
+ n += (str.size - rv.size)
+ str = rv
end while true
end
end
diff --git a/lib/yahns/wbuf.rb b/lib/yahns/wbuf.rb
index 1a24aab..f857a60 100644
--- a/lib/yahns/wbuf.rb
+++ b/lib/yahns/wbuf.rb
@@ -50,12 +50,12 @@ class Yahns::Wbuf # :nodoc:
# try to bypass the VFS layer and write directly to the socket
# if we're all caught up
case rv = String === buf ? c.kgio_trywrite(buf) : c.kgio_trywritev(buf)
- when String, Array
- buf = rv # retry in loop
when nil
return # yay! hopefully we don't have to buffer again
when :wait_writable, :wait_readable
@busy = rv
+ else # String, Array
+ buf = rv # retry in loop
end until @busy
@tmpio ||= Yahns::TmpIO.new(@tmpdir)
diff --git a/lib/yahns/wbuf_str.rb b/lib/yahns/wbuf_str.rb
index 89dfd33..a997a76 100644
--- a/lib/yahns/wbuf_str.rb
+++ b/lib/yahns/wbuf_str.rb
@@ -27,12 +27,12 @@ class Yahns::WbufStr # :nodoc:
def wbuf_flush(client)
case rv = client.kgio_trywrite(@str)
- when String
- @str = rv
when :wait_writable, :wait_readable
return rv
when nil
return @next
+ else # String
+ @str = rv
end while true
end
end
diff --git a/lib/yahns/worker.rb b/lib/yahns/worker.rb
index d6e7364..aceaf4e 100644
--- a/lib/yahns/worker.rb
+++ b/lib/yahns/worker.rb
@@ -24,17 +24,17 @@ class Yahns::Worker # :nodoc:
# dies unexpectedly.
def yahns_step
case buf = @to_io.kgio_tryread(4)
- when String
- # unpack the buffer and trigger the signal handler
- signum = buf.unpack('l')
- fake_sig(signum[0])
- # keep looping, more signals may be queued
when nil # EOF: master died, but we are at a safe place to exit
fake_sig(:QUIT)
@to_io.close
return :ignore
when :wait_readable # keep waiting
return :ignore
+ else # String
+ # unpack the buffer and trigger the signal handler
+ signum = buf.unpack('l')
+ fake_sig(signum[0])
+ # keep looping, more signals may be queued
end while true # loop, as multiple signals may be sent
end
--
EW
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [WIP v2] rely on optimized case dispatch
2015-12-04 22:49 [WIP] rely on optimized case dispatch Eric Wong
@ 2015-12-08 5:19 ` Eric Wong
0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2015-12-08 5:19 UTC (permalink / raw)
To: yahns-public
Ruby-trunk (as of r52931) optimizes case dispatch for additional
immediate values such as `nil', `true', and `false'.
Rearrange our case statements (and take away some safety-checks
:x) to take advantage of these optimizations in ruby-trunk.
ref:
https://bugs.ruby-lang.org/issues/11769
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/71818
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/71825
---
No actual improvements in synthetic benchmarks, yet. It'll be
worth investigating optimizing "Ruby constant" in when cases, too.
Additional tweak inside the :headers of http_client.rb (yahns_step)
when checking the kgio_tryread result
| 2 +-
lib/yahns/http_client.rb | 34 +++++++++++++--------------
lib/yahns/http_response.rb | 26 ++++++++++-----------
lib/yahns/proxy_http_response.rb | 50 ++++++++++++++++++++--------------------
lib/yahns/sendfile_compat.rb | 6 ++---
lib/yahns/wbuf.rb | 4 ++--
lib/yahns/wbuf_str.rb | 4 ++--
lib/yahns/worker.rb | 10 ++++----
8 files changed, 67 insertions(+), 69 deletions(-)
--git a/extras/proxy_pass.rb b/extras/proxy_pass.rb
index 29dd995..bfe3b8f 100644
--- a/extras/proxy_pass.rb
+++ b/extras/proxy_pass.rb
@@ -61,7 +61,7 @@ def req_write(buf, timeout)
kgio_wait_writable(wait_time)
when nil
return
- when String
+ else # String
buf = rv
end while true
end
diff --git a/lib/yahns/http_client.rb b/lib/yahns/http_client.rb
index db53587..117300e 100644
--- a/lib/yahns/http_client.rb
+++ b/lib/yahns/http_client.rb
@@ -28,15 +28,13 @@ def step_write
when :ignore # :ignore on hijack
@state = :ignore
return :ignore
- when Yahns::StreamFile
- @state = rv # continue looping
when true, false # done
return http_response_done(rv)
when :ccc_done, :r100_done
@state = rv
return :wait_writable
- else
- raise "BUG: #{@state.inspect}#wbuf_flush returned #{rv.inspect}"
+ else # Yahns::StreamFile
+ @state = rv # continue looping
end while true
end
@@ -79,14 +77,14 @@ def input_ready
# returns :wait_readable/wait_writable/nil to yield back to epoll
def fill_body(rsize, rbuf)
case rv = kgio_tryread(rsize, rbuf)
- when String
- @hs.filter_body(rbuf, @hs.buf << rbuf)
- @input.write(rbuf)
- true # keep looping on kgio_tryread (but check body_eof? first)
when :wait_readable, :wait_writable
rv # have epoll/kqueue wait for more
when nil # unexpected EOF
@input.close # nil
+ else # String
+ @hs.filter_body(rbuf, @hs.buf << rbuf)
+ @input.write(rbuf)
+ true # keep looping on kgio_tryread (but check body_eof? first)
end
end
@@ -94,16 +92,16 @@ def fill_body(rsize, rbuf)
# returns :wait_readable/wait_writable/nil to yield back to epoll
def read_trailers(rsize, rbuf)
case rv = kgio_tryread(rsize, rbuf)
- when String
+ when :wait_readable, :wait_writable
+ return rv # wait for more
+ when nil # unexpected EOF
+ return @input.close # nil
+ else # String
if @hs.add_parse(rbuf)
@input.rewind
return true
end
# keep looping on kgio_tryread...
- when :wait_readable, :wait_writable
- return rv # wait for more
- when nil # unexpected EOF
- return @input.close # nil
end while true
end
@@ -132,7 +130,9 @@ def yahns_step
# continue to outer loop
when :headers
case rv = kgio_tryread(k.client_header_buffer_size, rbuf)
- when String
+ when :wait_readable, :wait_writable, nil
+ return rv
+ else # String
if @hs.add_parse(rv)
case input = input_ready
when :wait_readable, :wait_writable, :close then return input
@@ -142,8 +142,6 @@ def yahns_step
end
end
# keep looping on kgio_tryread
- when :wait_readable, :wait_writable, nil
- return rv
end while true
when :body
if @hs.body_eof?
@@ -234,12 +232,12 @@ def kgio_wait_readable(timeout = self.class.client_timeout)
# used by StreamInput (and thus TeeInput) for input_buffering {false|:lazy}
def yahns_read(bytes, buf)
case rv = kgio_tryread(bytes, buf)
- when String, nil
- return rv
when :wait_readable
kgio_wait_readable or raise Yahns::ClientTimeout, "waiting for read", []
when :wait_writable
kgio_wait_writable or raise Yahns::ClientTimeout, "waiting for write", []
+ else # String, nil
+ return rv
end while true
end
diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb
index 99bf664..cbfcf77 100644
--- a/lib/yahns/http_response.rb
+++ b/lib/yahns/http_response.rb
@@ -75,11 +75,11 @@ def wbuf_maybe(wbuf, rv)
case rv = wbuf.wbuf_close(self)
when :ignore # hijacked
@state = rv
- when Yahns::StreamFile
- @state = rv
- :wait_writable
when true, false
http_response_done(rv)
+ else # Yahns::StreamFile
+ @state = rv
+ :wait_writable
end
else
@state = wbuf
@@ -162,9 +162,6 @@ def http_response_write(status, headers, body)
case rv = kgio_syssend(buf, flags)
when nil # all done, likely
break
- when String
- flags = MSG_DONTWAIT
- buf = rv # hope the skb grows
when :wait_writable, :wait_readable
if k.output_buffering
alive = hijack ? hijack : alive
@@ -174,6 +171,9 @@ def http_response_write(status, headers, body)
else
response_wait_write(rv) or return :close
end
+ else # String
+ flags = MSG_DONTWAIT
+ buf = rv # hope the skb grows
end while true
end
@@ -192,8 +192,6 @@ def http_response_write(status, headers, body)
case rv = kgio_trywrite(chunk)
when nil # all done, likely and good!
break
- when String
- chunk = rv # hope the skb grows when we loop into the trywrite
when :wait_writable, :wait_readable
if k.output_buffering
wbuf = Yahns::Wbuf.new(body, alive, k.output_buffer_tmpdir, rv)
@@ -202,6 +200,8 @@ def http_response_write(status, headers, body)
else
response_wait_write(rv) or return :close
end
+ else # String
+ chunk = rv # hope the skb grows when we loop into the trywrite
end while true
end
end
@@ -231,8 +231,6 @@ def do_ccc
case rv = kgio_trywrite(buf)
when nil
break
- when String
- buf = rv
when :wait_writable, :wait_readable
if self.class.output_buffering
wbuf = buf.dup
@@ -241,6 +239,8 @@ def do_ccc
else
response_wait_write(rv) or return :close
end
+ else # String
+ buf = rv
end while true
end
end
@@ -257,8 +257,6 @@ def http_100_response(env)
: "HTTP/1.1 100 Continue\r\n\r\n".freeze
case rv = kgio_trywrite(buf)
- when String
- buf = rv
when :wait_writable, :wait_readable
if self.class.output_buffering
@state = Yahns::WbufStr.new(buf, :r100_done)
@@ -266,8 +264,10 @@ def http_100_response(env)
else
response_wait_write(rv) or return :close
end
- else
+ when nil
return rv
+ else # String
+ buf = rv
end while true
end
end
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index 3858456..13f8870 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -13,12 +13,12 @@ def proxy_write(wbuf, buf, alive)
# no write buffer, try to write directly to the client socket
case rv = String === buf ? kgio_trywrite(buf) : kgio_trywritev(buf)
when nil then return # done writing buf, likely
- when String, Array # partial write, hope the skb grows
- buf = rv
when :wait_writable, :wait_readable
wbuf = Yahns::Wbuf.new(nil, alive, self.class.output_buffer_tmpdir, rv)
buf = buf.join if Array === buf
break
+ else # String, Array # partial write, hope the skb grows
+ buf = rv
end while true
end
@@ -97,12 +97,12 @@ def proxy_response_start(res, tip, kcar, req_res)
# send the headers
case rv = kgio_syssend(res, flags)
when nil then break # all done, likely
- when String # partial write, highly unlikely
- flags = MSG_DONTWAIT
- res = rv # hope the skb grows
when :wait_writable, :wait_readable # highly unlikely in real apps
wbuf = proxy_write(nil, res, alive)
break # keep buffering as much as possible
+ else # String # partial write, highly unlikely
+ flags = MSG_DONTWAIT
+ res = rv # hope the skb grows
end while true
rbuf = Thread.current[:yahns_rbuf]
@@ -112,26 +112,26 @@ def proxy_response_start(res, tip, kcar, req_res)
if len = kcar.body_bytes_left
case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
- when String
- len = kcar.body_bytes_left -= tmp.size
- wbuf = proxy_write(wbuf, tmp, alive)
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
+ else # String
+ len = kcar.body_bytes_left -= tmp.size
+ wbuf = proxy_write(wbuf, tmp, alive)
end until len == 0
elsif kcar.chunked? # nasty chunked body
req_res.proxy_trailers = nil # define to avoid warnings for now
buf = ''
case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
- when String
- kcar.filter_body(buf, tmp)
- wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty?
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
+ else # String
+ kcar.filter_body(buf, tmp)
+ wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty?
end until kcar.body_eof?
buf = tmp
@@ -139,12 +139,12 @@ def proxy_response_start(res, tip, kcar, req_res)
rbuf = Thread.current[:yahns_rbuf] = ''
until kcar.trailers(tlr, buf)
case rv = req_res.kgio_tryread(0x2000, rbuf)
- when String
- buf << rv
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
+ else # String
+ buf << rv
end # no loop here
end
wbuf = proxy_write(wbuf, trailer_out(tlr), alive)
@@ -152,13 +152,13 @@ def proxy_response_start(res, tip, kcar, req_res)
else # no Content-Length or Transfer-Encoding: chunked, wait on EOF!
case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf)
- when String
- wbuf = proxy_write(wbuf, tmp, alive)
when nil
req_res.shutdown
break
when :wait_readable
return wait_on_upstream(req_res, alive, wbuf)
+ else # String
+ wbuf = proxy_write(wbuf, tmp, alive)
end while true
end
@@ -176,13 +176,13 @@ def proxy_response_finish(kcar, wbuf, req_res)
if len = kcar.body_bytes_left
case tmp = req_res.kgio_tryread(0x2000, rbuf)
- when String
- len = kcar.body_bytes_left -= tmp.size
- wbuf.wbuf_write(self, tmp)
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return :wait_readable # self remains in :ignore, wait on upstream
+ else # String
+ len = kcar.body_bytes_left -= tmp.size
+ wbuf.wbuf_write(self, tmp)
end while len != 0
elsif kcar.chunked? # nasty chunked body
@@ -191,13 +191,13 @@ def proxy_response_finish(kcar, wbuf, req_res)
unless req_res.proxy_trailers
# are we done dechunking the main body, yet?
case tmp = req_res.kgio_tryread(0x2000, rbuf)
- when String
- kcar.filter_body(buf, tmp)
- buf.empty? or wbuf.wbuf_write(self, chunk_out(buf))
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
when :wait_readable
return :wait_readable # self remains in :ignore, wait on upstream
+ else # String
+ kcar.filter_body(buf, tmp)
+ buf.empty? or wbuf.wbuf_write(self, chunk_out(buf))
end until kcar.body_eof?
req_res.proxy_trailers = [ tmp, [] ] # onto trailers!
rbuf = Thread.current[:yahns_rbuf] = ''
@@ -206,12 +206,12 @@ def proxy_response_finish(kcar, wbuf, req_res)
buf, tlr = *req_res.proxy_trailers
until kcar.trailers(tlr, buf)
case rv = req_res.kgio_tryread(0x2000, rbuf)
- when String
- buf << rv
when :wait_readable
return :wait_readable
when nil # premature EOF
return proxy_err_response(nil, req_res, nil, wbuf)
+ else # String
+ buf << rv
end # no loop here
end
wbuf.wbuf_write(self, trailer_out(tlr))
@@ -219,13 +219,13 @@ def proxy_response_finish(kcar, wbuf, req_res)
else # no Content-Length or Transfer-Encoding: chunked, wait on EOF!
case tmp = req_res.kgio_tryread(0x2000, rbuf)
- when String
- wbuf.wbuf_write(self, tmp)
when nil
req_res.shutdown
break
when :wait_readable
return :wait_readable # self remains in :ignore, wait on upstream
+ else # String
+ wbuf.wbuf_write(self, tmp)
end while true
end
diff --git a/lib/yahns/sendfile_compat.rb b/lib/yahns/sendfile_compat.rb
index da2a9ec..6d4cc56 100644
--- a/lib/yahns/sendfile_compat.rb
+++ b/lib/yahns/sendfile_compat.rb
@@ -11,13 +11,13 @@ def trysendfile(io, offset, count)
str = io.read(count, buf) or return # nil for EOF
n = 0
case rv = kgio_trywrite(str)
- when String # partial write, keep trying
- n += (str.size - rv.size)
- str = rv
when :wait_writable, :wait_readable
return n > 0 ? n : rv
when nil
return n + str.size # yay!
+ else # String # partial write, keep trying
+ n += (str.size - rv.size)
+ str = rv
end while true
end
end
diff --git a/lib/yahns/wbuf.rb b/lib/yahns/wbuf.rb
index 1a24aab..f857a60 100644
--- a/lib/yahns/wbuf.rb
+++ b/lib/yahns/wbuf.rb
@@ -50,12 +50,12 @@ def wbuf_write(c, buf)
# try to bypass the VFS layer and write directly to the socket
# if we're all caught up
case rv = String === buf ? c.kgio_trywrite(buf) : c.kgio_trywritev(buf)
- when String, Array
- buf = rv # retry in loop
when nil
return # yay! hopefully we don't have to buffer again
when :wait_writable, :wait_readable
@busy = rv
+ else # String, Array
+ buf = rv # retry in loop
end until @busy
@tmpio ||= Yahns::TmpIO.new(@tmpdir)
diff --git a/lib/yahns/wbuf_str.rb b/lib/yahns/wbuf_str.rb
index 89dfd33..a997a76 100644
--- a/lib/yahns/wbuf_str.rb
+++ b/lib/yahns/wbuf_str.rb
@@ -27,12 +27,12 @@ def initialize(str, next_state)
def wbuf_flush(client)
case rv = client.kgio_trywrite(@str)
- when String
- @str = rv
when :wait_writable, :wait_readable
return rv
when nil
return @next
+ else # String
+ @str = rv
end while true
end
end
diff --git a/lib/yahns/worker.rb b/lib/yahns/worker.rb
index d6e7364..aceaf4e 100644
--- a/lib/yahns/worker.rb
+++ b/lib/yahns/worker.rb
@@ -24,17 +24,17 @@ def atfork_parent
# dies unexpectedly.
def yahns_step
case buf = @to_io.kgio_tryread(4)
- when String
- # unpack the buffer and trigger the signal handler
- signum = buf.unpack('l')
- fake_sig(signum[0])
- # keep looping, more signals may be queued
when nil # EOF: master died, but we are at a safe place to exit
fake_sig(:QUIT)
@to_io.close
return :ignore
when :wait_readable # keep waiting
return :ignore
+ else # String
+ # unpack the buffer and trigger the signal handler
+ signum = buf.unpack('l')
+ fake_sig(signum[0])
+ # keep looping, more signals may be queued
end while true # loop, as multiple signals may be sent
end
--
EW
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-12-08 5:19 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-04 22:49 [WIP] rely on optimized case dispatch Eric Wong
2015-12-08 5:19 ` [WIP v2] " Eric Wong
Code repositories for project(s) associated with this public inbox
https://yhbt.net/yahns.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).