about summary refs log tree commit homepage
DateCommit message (Collapse)
2015-04-24proxy_pass: clear backtrace on ECONNREFUSED
Bad connections or dead upstreams cannot be solved looking at a backtrace, so avoid polluting logs with them and making other problems less visible.
2015-04-22favor #nil? instead of "== nil" comparisons in cold code
We don't need optimized dispatch methods in cold code, so use the more space-efficient "nil?" method dispatch to save us one word per-call site for a rough total of 24 bytes saving.
2015-04-22config: avoid unnecessary binmode call
We may set binary mode upon open by passing "b" in the mode string, so avoid the extra method dispatch and bytecode/cache overhead that entails.
2015-04-21proxy_pass: fix race condition due to flawed hijack check
The entire idea of a one-shot-based design is all the mutual exclusion is handled by the event dispatch mechanism (epoll or kqueue) without burdening the user with extra locking. However, the way the hijack works means we check the Rack env for the 'rack.hijack_io' key which is shared across requests and may be cleared. Ideally, this would not be a problem if the Rack dispatch allowed returning a special value (e.g. ":ignore") instead of the normal status-headers-body array, much like what the non-standard "async.callback" API Thin started. We could also avoid this problem by disallowing our "unhijack-ing" of the socket but at a significant cost of crippling code reusability, including that of existing middleware. Thus, we allocate a new, empty request object here to avoid a TOCTTOU in the following timeline: original thread: | another thread HttpClient#yahns_step | r = k.app.call(env = @hs.env) # socket hijacked into epoll queue <thread is scheduled away> | epoll_wait readiness | ReqRes#yahns_step | proxy dispatch ... | proxy_busy_mod_done ************************** DANGER BELOW ******************************** | HttpClient#yahns_step | # clears env # sees empty env: | return :ignore if env.include?('rack.hijack_io') | In other words, we cannot ever touch the original env seen by the original thread since it must see the 'rack.hijack_io' value because both are operating in the same Yahns::HttpClient object. This will happen regardless of GVL existence. Avoiding errors like this is absolutely critical to every one-shot based design.
2015-04-11proxy_pass: attempt to forward premature upstream responses
Upstreams may shut us down while we're writing a request body, attempt to forward any responses from the upstream back to the client which may explain the rejection reason for giant uploads.
2015-04-09proxy_pass: capture local variable earlier for rescue
This giant method needs to spew an error response in case uploads to the upstream fail, ensure the local variable is defined early.
2015-04-08proxy_pass: support backends which rely on EOF to terminate
Not all backends are capable of generating chunked responses (especially not to HTTP/1.0 clients) nor can they generate the Content-Length (especially when gzipping), so they'll close the socket to signal EOF instead.
2015-04-07extras/proxy_pass: reinstate synchronous version
Since yahns/proxy_pass is not a drop-in replacement, reinstate the old, synchronous version to avoid breaking existing setups which require Rack middleware support.
2015-04-07wbuf: fix writev calls for vectors
kgio_writev returns nil on success instead of the number of bytes written, so we must manually calculate the number of bytes written intead :x This is triggerable when sending giant chunked responses.
2015-04-07proxy_pass: avoid needless regexp
A dumb string comparison will do here, so there's no point in paying the memory and CPU cost of a regexp match when we already extracted the suffix from a header key.
2015-04-07proxy_pass: possibly avoid breaking some middlewares
hijack seems incompatible with many middlewares, so return a wonky response tuplet just in case...
2015-04-07http_context: avoid defining our own *buffer_tmpdir methods
Instance variable attr methods are cheaper and we can shove the complexity down to tmpio by allowing it to accept a nil argument for the temporary directory. This adds 4 bytes to tmpio but removes over 1K in http_context on a 32-bit system.
2015-04-07use String#include? for cold, simple substring matches
Literal regexps costs over 400 bytes of memory on x86-64 per-site, so there's no point in using them to cause bloat at cold call sites where runtime performance does not matter.
2015-04-07test/test_proxy_pass: remove buffer size tuning
On one of my ancient, cache-starved home systems, this tends to cause pathologically bad performance during some of these tests.
2015-04-07proxy_pass: send 1.0 requests to upstreams for 1.0 clients
We cannot pass trailers from upstreams to HTTP/1.0 clients without fully-buffering the response body AND trailers before forwarding the response header. Of course, one of the reasons yahns exists is to support lazy buffering, so fully-buffering up front is wasteful and hurts latency. So instead, degrade to 1.0 requests to upstreams for HTTP/1.0 clients, this should prevent upstreams from sending trailers in the first place. HTTP/1.0 clients on Rails apps may suffer, but there probably are not too many HTTP/1.0 clients out there.
2015-04-07proxy_pass: preliminary support for passing trailers
Rack apps may (through a round-about way) send HTTP trailers to HTTP/1.1 clients, and we need a way to forward those responses through without losing the trailers.
2015-04-04proxy_pass: more tests for giant headers and truncations
We need to ensure more uncommon cases such as gigantic upstream headers and truncated upstream responses are handled properly and predictably.
2015-04-03proxy_pass: expand pipelining tests for after-upload behavior
Pipelining uploads is rare in practice, but they must behave properly in case some brave soul wants to start doing it.
2015-04-03proxy_pass: test for truncated response behavior
Even if a response is screwed, we need to ensure breakage is predictable.
2015-04-03proxy_pass: test and fix larger uploads
We were incorrectly stashing the return value of detach_rbuf! into the inter-thread buffer buffer which is bound to the client.
2015-04-03proxy_pass: rewrite to be async, using rack.hijack
This allows our reverse proxy to avoid having an innefficient 1:1 relationship between threads and upstream connections, reducing memory usage when there are many upstream connections (possibly to multiple backend machines).
2015-04-03allow vector args to wbuf_write
This allows us to write chunked response bodies without extra copying to clients which support streaming.
2015-04-03http_client: preserve HTTP state after hijack
We'll be supporting "un-hijacking" a client socket for proxy_pass and we must preserve state for pipelined requests.
2015-04-03wbuf: store busy signal inside this object
This should make it easier to track state for asynchronous proxy_pass buffering.
2015-04-01tmpio: add writev support via kgio
This will allow us to write arrays for chunked output without unnecessary data copies.
2015-04-01test/test_proxy_pass: rename test name, too
This is no longer a part of the "extras" section
2015-04-01doc: note possible removal of client_body_buffer_size
This is probably the least useful tuning knob and may be removed in the future; so at least warn users about it. ref: <CAA2_N1t_UJZO9Vu9vx3NxysCx+okip8_pM+NpwhHrExM+f1e+Q@mail.gmail.com>
2015-03-17avoid EPOLL_CTL_DEL calls on rack.hijack
We will support "un-hijacking", so the repeated ep_insert/ep_remove sequences in the kernel will get expensive and complicated for our user-land code, too.
2015-03-14proxy_pass: officially become a part of yahns
This will rely on rack.hijack in the future to support asynchronous execution without tying up a thread when waiting for upstreams. For now, this allows simpler code with fewer checks and the use of monotonic time on newer versions of Ruby.
2015-03-14extras/proxy_pass: support Unix domain sockets as backends
Of course, some users will prefer to bind HTTP application servers to Unix domain sockets for better isolation and (maybe) better performance.
2015-03-14extras/proxy_pass: implicit $fullpath expansion for upstreams
This is slightly more nginx-style behavior and allows simpler configuration.
2015-03-14http_client: hijack after 100-continue disables HTTP response
While rack.hijack usage during application dispatch normally prevents yahns from writing an HTTP response out of the Rack response array, this was not correctly prevented when the application emitted a 100-continue response when the client was was too slow to read the 100-continue response without triggering response buffering the server. This bug only affects exceeding rare apps which rely on both rack.hijack use during app dispatch _and_ emits 100-continue responses, and even then it only affects slow clients which refuse to read the 100-continue response sent by yahns without blocking.
2015-03-13http_client: do not close input on hijack
We probably do not want env["rack.input"] to become unusable upon hijacking. Only drop the internal reference to it so it can eventually become garbage-collected, but there's no point in making env["rack.input"] unreadable.
2015-03-13avoid unnecessary calls #to_sym for __send__
No point in bloating our bytecode for single-use variables.
2015-03-13extras/proxy_pass: remove ERROR_502 constant
Some middlewares may attempt to modify the response body in place, so sharing this is not a good idea. We shouldn't really care about rare 502 error paths, either.
2015-03-13test/test_server: fix leftover process from inherit test
Oops, this test bug was introduced in: commit e413325737f23c5ec27a02246f95077bc1fb038d ("acceptor: close inherited-but-unneeded sockets")
2015-03-12extras/proxy_pass: remove unused CHUNK_SIZE constant
It was never used.
2015-03-09yahns 1.6.0 - reduced allocations and bugfixes v1.6.0
This release fixes a bug where previously-configured-but-now-removed listeners were inherited across USR2 upgrades are not shutdown immediately in the child. There are also minor reductions in allocations which can save a few hundred bytes statically and also whenever write buffering is necessary for large responses. Some minor documentation updates improvements in extras, too. shortlog of changes since 1.5.0: README: add link to mailing list archives test_ssl: factor out server SSLContext creation doc: add design_notes document reduce File::Stat object allocations update comments about wbuf_close return values wbuf: lazily (re)create temporary file fix compatibility with unicorn.git skip tests requiring String#b on 1.9.3 use the monotonic clock under Ruby 2.1+ favor Class.new for method-less classes extras/proxy_pass: save memory in String#split arg extras/proxy_pass: do not name unused variable extras/proxy_pass: log exceptions leading to 502 extras/proxy_pass: flesh out upload support + tests acceptor: close inherited-but-unneeded sockets See the git repository for more: git clone git://yhbt.net/yahns
2015-03-09acceptor: close inherited-but-unneeded sockets
When inheriting sockets from the parent via YAHNS_FD, we must close sockets ASAP if they are unconfigured in the child. This bug exists in yahns (and not unicorn) because of the trickier shutdown routine we do for blocking accept system calls to work reliably with the threading support in mainline Ruby 2.x. This bug would not exist in a purely C server using blocking accept, either.
2015-03-03extras/proxy_pass: flesh out upload support + tests
This module will probably become an official part of yahns soon, so finally add tests for this module.
2015-03-03extras/proxy_pass: log exceptions leading to 502
It may be useful for us to track down potential errors in our code or log when an upstream misbehaves.
2015-03-03extras/proxy_pass: do not name unused variable
"ruby -w" warns on it.
2015-02-10extras/proxy_pass: save memory in String#split arg
This saves over 400 bytes of memory in a cold code path.
2015-02-10favor Class.new for method-less classes
This saves over 400 bytes on x86-64.
2015-02-05use the monotonic clock under Ruby 2.1+
The monotonic clock is immune to time adjustments so it is not thrown off by misconfigured clocks. Process.clock_gettime also generates less garbage on 64-bit systems due to the use of Flonum.
2015-02-05skip tests requiring String#b on 1.9.3
While 1.9.3 support will probably be kept for another year or so, it's probably not worth supporting non-critical extras/ stuff on 1.9.3.
2015-02-05fix compatibility with unicorn.git
Install workarounds for running with unreleased versions of unicorn for now, as unicorn 5.x will be dropping many needless features.
2015-01-24wbuf: lazily (re)create temporary file
We may not need this temporary file if we've flushed everything out and entered bypass mode.
2015-01-24update comments about wbuf_close return values
The state management has evolved slightly over time, so update the comments to reflect that.
2015-01-23reduce File::Stat object allocations
Since we only support 1.9.3+, io.stat.size may be simplified to io.size to reduce allocations of File::Stat objects.