Date | Commit message (Collapse) |
|
epoll_wait() wakeups from QueueQuitter got lost during graceful
shutdown since there's multiple worker threads operating off the
same FD. Workaround the problem by re-arming the eventfd for
every worker thread reaped.
Link: https://yhbt.net/lore/lkml/20210405231025.33829-1-dave@stgolabs.net/
|
|
This should prevent missed/delayed wakeups if repeatedly
kill(2)-ed.
|
|
Might as well... this has been in use at YHBT.net for ~4 years
at this point. And given nginx has new corporate overlords,
maybe a decidedly non-enterprisey alternative is worth
"marketing" :P
Previous discussion from 2016:
https://YHBT.net/yahns-public/20160220081619.GA10850@dcvr.yhbt.net/
|
|
Linux before 4.9 (and before 3.16.57) failed to account
for the existing size of a pipe before checking system
resource limits and would return EPERM in that case.
https://80x24.org/mirrors/linux.git/commit?id=b0b91d18e2e97b741b294af9333824ecc3fadfd8
https://lore.kernel.org/lkml/?q=s%3A%22fix+limit+checking+in+pipe_set_size%22
Based on a patch by Stephen Demjanenko for unicorn:
https://bogomips.org/unicorn-public/1556922018-24096-1-git-send-email-sdemjanenko@gmail.com/
|
|
I've gotten cgit to work well for browsers without CSS
support (patches posted to <cgit@lists.zx2c4.com>).
For browsers with CSS support, the color scheme
is now dark and can help save electricity for users
of OLED and CRT displays.
|
|
And slightly cleanup the Kgio::DefaultWaiters include for
the eventfd path, too.
Fixes: 96825e8ca734cfbb ("remove calls to kgio_wait_* able")
|
|
Otherwise, listeners may still be injecting into the queue
and new clients may be accepted.
Fixes: 86ea6ed1417b ("server: respect shutdown_timeout")
|
|
IO#wait_readable existed since Ruby 2.0, so we don't need
to use the "kgio_"-prefixed version.
|
|
Old kernels running on alpha may EINVAL, here; but
modern kernels will automatically increase the passed
value to the minimum size supported by the kernel.
This only affects alpha, since all other arches use 4K
page size on Linux.
|
|
Slowly removing kgio dependencies...
|
|
Still not sure what's going on with the proxy_pass code,
but something in the Fdmap code is causing shutdowns to
take way longer than expected...
|
|
It seems there is still a bug in the proxy code which causes
this timeout expiries to be missed.
|
|
Ruby itself has tests for RNG reseeding at fork, so no need for
belt-and-suspenders code on our end.
|
|
Golfing to eliminate a constant lookup and inline-constant-cache entry
|
|
We use eventfd whereever possible, but workers still require
a pipe to the parent for death detection.
|
|
Since we've required Ruby 2.0+ for a while, we can assume
descriptors are created with IO#close_on_exec=true and
avoid bloating our code with calls to it.
|
|
Without sendfile, we can hit EOFError on IO#pread
if a file we're serving gets truncated mid-response.
This was causing test_truncated_sendfile failures;
but I didn't notice before because I forgot to set
SENDFILE_BROKEN=1 to disable the test.
|
|
Since we rely on this class being an IO-like class,
in Yahns::Queue#worker_thread we're using this method.
This fixes an actual error on lib/yahns/queue_kqueue.rb:56
|
|
In the future, this will allow sharing open files across
different clients when serving static files. For now, it
saves us one syscall.
|
|
Whenever @ssl.write_nonblock fails due to ECONNRESET/EPIPE in
Rack::Deflater#each; Rack::Deflater#each will still attempt to
write again in the "ensure" statement via Zlib::GzipWriter#close.
This causes SSL_write to complain of "bad length" or
"bad write retry" errors. Now, re-raise any SystemCallError
we caught from previous write_nonblock calls to prevent
calls to SSL_write which would trigger such an exception.
|
|
Errors which are the fault of the client should not generate
backtraces which can lead to dinky servers running out-of-space.
|
|
Oops. Occasionally my brain experiences packet loss :x
|
|
Since the common case is still to run a single app inside yahns,
we can simplify setup a bit for systemd (and like) users by
allowing them to omit the "listen" directive when they are
running a single app in yahns.
|
|
No point in optimizing for the single listener case in
setup code.
|
|
Support for it may be removed in future versions of Ruby(*),
and we actually do not need to waste time looping when
a instance variable will do.
(*) https://bugs.ruby-lang.org/issues/13245
|
|
Remove false statements about close-on-exec being cleared in the
parent process (verified via strace) and refactor the code to
take full advantage of options for Process.spawn and Process.exec.
This avoids unnecessary CoW traffic for the common case where
before_exec is unset.
|
|
"call" is a generic name and may not obvious to somebody
new to the code.
|
|
That object is not a Rack app, so lets avoid confusing
ourselves.
|
|
Although we do not publish RDoc-generated documentation on our
website, other places may, an people use ri(1) locally.
|
|
Iterating through the response body can be time consuming and
allocate memory, so nil out the headers object when we're done
with it to give Ruby a chance to recover the memory.
|
|
We try to cleanup after ourselves if possible so future mallocs
can find memory more easily. We do not need to nil the object
slot, just String#clear since we're exiting the function soon,
anyways.
Followup to commit bb774680aae0a827f887761b18da304aa94111cc
("use String#clear for short-lived buffers we create")
|
|
It's rare to have an empty string returned by `read` since it
requires a length argument of zero (careless) or nil (danger!
OOM!). Lets not try to optimize away a method dispatch in this
case by checking .size (optimized instruction in YARV).
Ruby IO#write already treats writing an empty string as a noop,
so no syscall is saved.
n.b. `gets` can return an empty string, too, but that's also
dangerous w.r.t. memory usage on untrusted input.
|
|
In case somebody stumbles upon it...
|
|
When entering StreamInput#read, it is common for @rbuf to
be drained and empty, meaning a simple String#clear can
be used in place of a more complex String#slice! String#replace
combo on an empty @rbuf.
While we're at it, we'll avoid an extra instructions for calling
`@rbuf.size` by storing the size in a local.
|
|
As with the previous commit
("response: do not set chunked header on bodyless responses"),
blindly setting "Transfer-Encoding: chunked" is wrong and
confuses "curl -T" on 204 responses, at least.
|
|
Setting "Transfer-Encoding: chunked" on responses will confuse
clients which see a 204 response and do not expect a body.
This follows Rack::Chunked behavior, as yahns should function
without Rack::Chunked middleware.
This regression appeared in yahns v1.13.0 (2016-08-05)
|
|
We still need to iterate through all response headers to support
response-only Rack hijacking. Previously, we only supported
full hijacking on so-called "HTTP/0.9" clients.
n.b. This diff will be easier to read with the
-b/--ignore-space-change option of git-diff(1) or GNU diff(1)
|
|
These comments have been outdated since 2013 with commit
cd84e2ccbdf2 ("ensure we stop all threads at exit")
|
|
If we already started writing a response, we cannot be sending a
502 to inform a user a connection has failed. This should
prevent errors from the OpenSSL layer about mismatched buffers
due to the combination of slow clients and upstreams prematurely
aborting.
|
|
Introduced in commit 08cea89483e90c79daa2c8efe70da6bdeba71147
('response: only stream "file" responses on known length')
|
|
This means we need to check Content-Length and use it
properly (unless Content-Range is set).
|
|
This is not a part of any Rack specification, and can lead to
interesting bugs with wrapped classes for gzip and TLS. AFAIK,
.to_io was meant to support IO#wait_*able and IO.select methods,
not to actually perform read/writes on the return value.
|
|
HTTPS adds some level of privacy protection and helps marketing
(because we care soooo much about good marketing! :P).
Performance-wise, this reduces subjectAltName bloat when
negotiating connections and will also speed up occasional
certificate renewals when/if we drop the old name.
Also, not occupying the document root of a domain will make it
easier to add alternative site locations in the future, because
centralization sucks and I don't like the idea of anybody paying
ICANN or similar entities for domain names.
|
|
Sometimes apps may trigger zero-byte chunks in the response
body for whatever reason. We should maintain consistent
behavior with the rest of kgio; and Ruby OpenSSL::SSL::SSLSocket
should maintain consistent behavior with the core IO class:
https://bugs.ruby-lang.org/issues/12660
|
|
We might as well do it since puma and thin both do(*),
and we can still do writev for now to get some speedups
by avoiding Rack::Chunked overhead.
timing runs of "curl --no-buffer http://127.0.0.1:9292/ >/dev/null"
results in a best case drop from ~260ms to ~205ms on one VM
by disabling Rack::Chunked in the below config.ru
$ ruby -I lib bin/yahns-rackup -E none config.ru
==> config.ru <==
class Body
STR = ' ' * 1024 * 16
def each
10000.times { yield STR }
end
end
use Rack::Chunked if ENV['RACK_CHUNKED']
run(lambda do |env|
[ 200, [ %w(Content-Type text/plain) ], Body.new ]
end)
(*) they can do Content-Length, but I don't think it's
worth the effort at the server level.
|
|
This makes it easier to add more parameters to
http_response_write and simplifies current callers.
|
|
Clients are not able to handle persistent connections unless
the client knows the length of the response.
|
|
Rack::Lint-compliant applications wouldn't have this problem;
but apparently public-facing Rack servers (webrick/puma/thin)
all implement this; so there is precedence for implementing
this in yahns itself.
|
|
This allows us to speed up subsequent calls to wbuf_write when
the client socket buffers are cleared. This doesn't affect
functionality outside of performance.
|
|
Since we use wbuf_lite for long, streaming requests, we need to
reset the offset and counts when aborting the existing wbuf and
not assume the wbuf goes out-of-scope and expires when we
are done using it. Fix stupid bugs in BUG notices while
we're at it :x
|