Date | Commit message (Collapse) |
|
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
|
|
Future updates may use the update-copyright script in gnulib:
git ls-files | UPDATE_COPYRIGHT_HOLDER='all contributors' \
UPDATE_COPYRIGHT_USE_INTERVALS=2 \
xargs /path/to/gnulib/build-aux/update-copyright
|
|
Unfortunately we cannot rely on the RubyVM for optimizing hash
deletions, yet, so manually freeze for this string since it
(unlike every line after it) is a hot path if handling request
bodies.
Update a comment while we're at it.
|
|
This saves around 200 bytes on x86-64 and potentially improves
CPU cache performance. This does not reduce inline method
cache overhead as String#<< already has optimized dispatch
support (opt_ltlt in insns.def in Ruby 1.9+)
|
|
Ruby (MRI) 2.1 optimizes allocations away on String#freeze with
literal strings.
Furthermore, Ruby 2.2 optimizes away literal string allocations
when they are used as arguments to Hash#[] and Hash#[]=
Thus we can avoid expensive constant lookups and cache overhead
by taking advantage of advancements in Ruby.
Since Ruby 2.2 has been out for 7 months, now; it ought to be safe
to introduce minor performance regressions for folks using older
Rubies (1.9.3+ remains supported) to benefit folks on the latest
Ruby.
|
|
Rack::Utils::HTTP_STATUS_CODES may be altered by the underlying
application, allow changes to that to be reflected in our responses
and do not rely on the Unicorn::HttpResponse::CODES hash which
will probably go away soon.
|
|
Middlewares such as Rack::Lock (used by Rails) break badly unless
the response body is closed on hijack, so we will close it to follow
the lead of other popular Rack servers.
While it's unclear if there's anybody using rack.hijack besides
yahns/proxy_pass we'll try to emulate the behavior of other servers
as much as possible.
ref: https://github.com/ngauthier/tubesock/issues/10
While we're at it, use DieIfUsed correctly in test_ssl.rb :x
|
|
We don't need to waste a valuable ivar slot on each socket
when we know unicorn already maintains this flag for us.
|
|
This should make it easier to track state for asynchronous
proxy_pass buffering.
|
|
Ruby 2.1 optimizes String#freeze by deduplicating string literal
calls to freeze. Ruby 2.2 _may_ also optimize away allocations to
Hash#delete in the future. In any case, this is uncommon code and
not worth trading permanent space to reduce temporal garbage.
While this favors Ruby 2.1 and later, it remains completely
compatible with Ruby 1.9.3 and 2.0.0.
|
|
Our kv_str method already fails if `$,' is a non-empty string.
Rack::Chunked and likely other middlewares fails when `$,' is
not empty, too, so supporting apps which set `$,' is probably
not feasible.
|
|
HTTP headers are compared case-insensitively, so we must filter out
the Date header case-insensitively. Found via casual code
inspection, I doubt anybody sets a Date header in Rack apps.
|
|
We must not cork response headers when the response body is empty,
otherwise those headers will be delayed by 200ms.
|
|
If Content-Length is known, try to save some bandwidth by
corking the headers until the body is sendable. This allows
us to avoid sending an extra packet for small HTTP responses.
This allows high-performance websites like YHBT.net to be served
faster!
|
|
Unicorn::HttpResponse#httpdate is currently not thread-safe without GVL.
|
|
We do not use these strings in string assignment, and we're not
in danger of modifying these strings in place, so do not freeze
them.
|
|
Simultaneously waiting for both readability and writability is
likely unnecessary. Sockets become writable much more commonly,
and if we need to read, we'll issue a read the next time it enters
yahns_step (after it becomes writable).
Also, this makes kqueue easier-to-implement as I don't believe it
implements a way to combine EVFILT_READ with EVFILT_WRITE
(especially not safely while relying on EV_ONESHOT behavior).
|
|
We can use the wbuf_close return value instead to ensure we close
tmpio properly and follow the same code path as a normal
(:wait_writable-triggering) buffered response would.
Add a few tests to ensure we properly close the response body
for exec_cgi, where I noticed zombies and started me down this
rabbit hole looking for places where the response body was not
closed properly.
|
|
We may buffer a response partially, but no longer need the
buffer if we entered bypass mode. When doing this, we must
remember to close the body after using it.
|
|
We allow applications to drop persistent connections, this does not
seem forbidden by Rack and gives the app author some control over
the lifetime of a connection.
|
|
We parse and use Content-Range, but do not drop it when sending
a response since that would confuse clients.
|
|
This allows users to specify alternative temporary directories
in case buffers get too large for one filesystem to handle or
to give priority to some clients on certain ports.
|
|
This saves about 200 bytes of unswappable kernel memory,
so it might matter for systems with many connections
when hijacking.
|
|
The write buffer may block on a single write and immediately
become unblocked afterwards. We need to account for this odd
corner case when serving static files; because clients can
trigger strange corner cases like this.
|
|
The tiny responses for check_client_connection and "100-Continue"
responses may occasionally fail with EAGAIN. We must be prepared
for those corner cases and buffer the output appropriately. We can
safely use a string for buffering here (for once(!)), since the
buffer sizes are bounded and known at buffer time, unlike the
response headers/bodies sent by the Rack application.
|
|
This should speed up out-of-the-box performance with curl
as well as allow input_buffering :lazy/true users to reject
requests they don't like.
|
|
Rack hijacking may close the socket before it yields control back to our
epoll event loop. So it's not safe to attempt to use the socket (or
even get the .fileno) with :delete/EPOLL_CTL_DEL.
So change :delete to :ignore, and only decrement the FD counter to allow
yahns to do graceful shutdown. This means we'll potentially waste ~200
bytes of kernel memory due to epoll overhead until the FD is closed by
the app hijacking.
I'm not sure how Rack servers handle graceful shutdown when
hijacking, but maybe they just retrap SIGQUIT...
|
|
Some users may wish to disable persistent connections for testing
or whatever reason, let them. We'll also be using this feature
to force SIGQUIT to expire clients.
|
|
Since we are smarter about closing @input, we can just call
.close on it as closing inputs is forbidden in Rack apps,
anyways. This reduces our class count and should make
things easier to follow.
|
|
|