Date | Commit message (Collapse) |
|
The perl-5.16.3-294.el7_6 RPM package on RHEL/CentOS 7 is
affected by a memory leak in Perl when calling `ref' on
blessed references. This resulted in a very slow leak that
manifests more quickly with a nonstop "git fetch" loop.
Use Scalar::Util::blessed to work around the issue.
Tested overnight on a CentOS 7 VM.
cf. https://rt.perl.org/Public/Bug/Display.html?id=114340
|
|
We support "-env" to clear the environment with spawn(),
which causes test failures but no runtime failures
(since "-env" isn't used anywhere in our real code)
Reported-and-tested-by: Alyssa Ross <hi@alyssa.is>
|
|
It was never used, and will not be needed.
|
|
We were emitting the same "<id>mailto:name@domain</id>" tag
for every feed (but not per-feed entry). This could cause
feed readers to mistake the top (news.atom) feed for other
feeds (search results, or per-thread feeds).
This is technically a breaking change for people relying on
per-thread or per-query feeds, but the only alternative is
to remain broken for anybody trying to follow multiple feeds
off the same inbox.
|
|
We need to handle arbitrary integers and case-insensitive
variations of human words to match git-config(1) behavior,
since that's what users would expect given we use config
files parseable by git-config(1).
|
|
Only removing $http->{env} is needed to prevent circular
references. $env->{'psgix.io'} does not need to be deleted
since $env will no longer have any references to it when
->close returns.
|
|
And explain why we need to do that delete in a comment.
|
|
Naming $start_cb consistently helps avoid confusing new readers,
and some comments will help with understanding flow
|
|
All of these circular references are designed to clear
themselves, but these will make actual errors from Devel::Cycle
easier-to-spot.
The circular reference in the limiter {run_queue} is not a real
problem, but we can avoid storing the circular reference until
we actually need to spawn the child, reducing the size of the
Qspawn object while it's in the queue, slightly.
We also do not need to have redundant checks to spawn new
processes, we should only spawn new processes when they're
->start-ed or after waitpid reaps them.
|
|
Generic PSGI servers have $env->{'psgi.errors'}, too,
so ensure they can log errors.
|
|
We don't use the return value in real code since we do waitpid
asynchronously, now. So simplify our runtime code at the cost
of making our test slighly more complex.
|
|
We don't need to hold onto the subprocess environ and
redirects/options for popen_rd after spawning the child process.
I do not expect this to fix problem of leaking unlinked regular
file descriptors (which I still can't reproduce), and it
definitely does not fix the problem of leaking pipe descriptors
(which I also can't reproduce).
This will save an FD sooner on non-public-inbox-httpd servers
which give a non-FD $env->{'psgi.input'}, however
Regardless, it's good to free up memory resources in our own
process ASAP we're done using them.
|
|
EINTR should not happen when using non-blocking sockets like we
do in our daemons, but maybe some OSes allow it to happen and
edge-triggered notifications won't notify us again.
So always retry immediately on EINTR without relying on kqueue
or epoll to notify us, and log any other unrecoverable errors
which may happen while we're at it.
|
|
We rely on DS to do waitpid with WNOHANG, now, and the non-DS
code path won't use WNOHANG.
|
|
Rename the {cleanup} field to {end}, since it's similar
to END {} and is consistent with the variable in Qspawn.pm
And document how certain subs get called, since we have
many subs named "new" and "close".
|
|
REMOTE_HOST is not set by us (it is the reverse DNS name) of
REMOTE_ADDR, and there's few better ways to kill HTTP server
performance than to use standard name resolution APIs like
getnameinfo(3).
|
|
Might as well share some code for temporary file creation
|
|
Although we always unlink temporary files, give them a
meaningful name so that we can we can still make sense
of the pre-unlink name when using lsof(8) or similar
tools on Linux.
|
|
I didn't know PerlIO::scalar existed until a few months ago,
but it's been distributed with Perl since 5.8 and doesn't
seem to be split out into it's own package on any distro.
|
|
For whatever reason, inbox directories can go missing
temporarily or permanently. Tell the admin about them
and continue on our way.
|
|
It's possible for Qspawn callers to be deferred, in which case
we must ensure we don't cause the temporary file used for
stdin to become unref-ed and closed.
This can be a problem when we exceed the default Qspawn
limiter of 32 concurrent processes for "git update-index".
|
|
|
|
We don't want to get hung into a state where we see "\n" via
index(), yet cannot consume rbuf in the while loop. So tweak
the regexp to ensure we always consume rbuf.
I suspect this is what causes occasional 100% CPU usage of
-nntpd, but reproducing it's been difficult..
|
|
Since Net::NNTP::listgroup doesn't support the range parameter,
I had to test this manually and noticed extra CRLF were emitted.
|
|
We don't need to keep an empty buffer around in the common case
when a client is sending us completely inflatable requests and
we're able to read them in one go.
This only seems to save about 2M with 10K NNTPS clients using
COMPRESS, so it's not a huge win, but better than nothing.
|
|
RFC3977 6.1.2.2 LISTGROUP allows a [range] arg after [group],
and supporting it allows NNTP support in neomutt to work again.
Tested with NeoMutt 20170113 (1.7.2) on Debian stretch
(oldstable)
|
|
RFC3977 8.4.2 mandates the order of non-standard headers
to be after the first seven standard headers/metadata;
so "Xref:" must appear after "Lines:"|":lines".
Additionally, non-required header names must be followed
by ":full".
Cc: Jonathan Corbet <corbet@lwn.net>
Reported-by: Urs Janßen
<E1hmKBw-0008Bq-8t@akw>
|
|
We won't need further layering after enabling compression. So
be explicit about which sub we're calling when we hit ->do_read
from NNTP and eliminate the need for the comment.
|
|
We need to ensure further timers can be registered if there's
currently no idle clients.
|
|
In HTTP.pm, we can use the same technique NNTP.pm uses with
long_response with the $long_cb callback and avoid storing
$pull in the per-client structure at all. We can also reuse
the same logic to push the callback into wbuf from NNTP.
This does NOT introduce a new circular reference, but documents
it more clearly.
|
|
We're using Qspawn, now
|
|
Relying on "use" to import during BEGIN means we get to take
advantage of prototype checking of function args during the rest
of the compilation phase.
|
|
*glob notation isn't always necessary, and there's
no need to disable 'once' warnings, this way.
|
|
No point in uglifying our code since we need the POSIX
module in many places, anyways.
|
|
* origin/nntp-compress:
nntp: improve error reporting for COMPRESS
nntp: reduce memory overhead of zlib
nntp: support COMPRESS DEFLATE per RFC 8054
nntp: move LINE_MAX constant to the top
nntp: use msg_more as a method
|
|
While we're usually not stuck waiting on waitpid after
seeing a pipe EOF or even triggering SIGPIPE in the process
(e.g. git-http-backend) we're reading from, it MAY happen
and we should be careful to never hang the daemon process
on waitpid calls.
v2: use "eq" for string comparison against 'DEFAULT'
|
|
Add some checks for errors at initialization, though there's not
much that can be done with ENOMEM-type errors aside from
dropping clients.
We can also get rid of the scary FIXME for MemLevel=8. It was a
stupid error on my part in the original per-client deflate
stream implementation calling C::R::Z::{Inflate,Deflate} in
array context and getting the extra dualvar error code as a
string result, causing the {zin}/{zout} array refs to have
extra array elements.
|
|
Using Z_FULL_FLUSH at the right places in our event loop, it
appears we can share a single zlib deflate context across ALL
clients in a process.
The zlib deflate context is the biggest factor in per-client
memory use, so being able to share that across many clients
results in a large memory savings.
With 10K idle-but-did-something NNTP clients connected to a
single process on a 64-bit system, TLS+DEFLATE used around
1.8 GB of RSS before this change. It now uses around 300 MB.
TLS via IO::Socket::SSL alone uses <200MB in the same situation,
so the actual memory reduction is over 10x.
This makes compression less efficient and bandwidth increases
around 45% in informal testing, but it's far better than no
compression at all. It's likely around the same level of
compression gzip gives on the HTTP side.
Security implications with TLS? I don't know, but I don't
really care, either... public-inbox-nntpd doesn't support
authentication and it's up to the client to enable compression.
It's not too different than Varnish caching gzipped responses
on the HTTP side and having responses go to multiple HTTPS
clients.
|
|
This is only tested so far with my patches to Net::NNTP at:
https://rt.cpan.org/Ticket/Display.html?id=129967
Memory use in C10K situations is disappointing, but that's
the nature of compression.
gzip compression over HTTPS does have the advantage of not
keeping zlib streams open when clients are idle, at the
cost of worse compression.
|
|
It'll be accessible from other places, and there was no real
point in having it declared inside a sub.
|
|
It's a tad slower, but we'll be able to subclass this to rely
on zlib deflate buffering. This is advantageous for TLS clients
since (AFAIK) IO::Socket::SSL/OpenSSL doesn't give us ways to use
MSG_MORE or writev(2) like like GNUTLS does.
|
|
Given most folks have multiple mail accounts, there's no reason
we can't support multiple Maildirs.
|
|
We can drop some unnecessary imports and now that we switched
to InboxWritable.
|
|
Diffstat summary comments were added to git last year and
we need to filter them out to get anchors working properly.
Reported-by: SZEDER Gábor <szeder.dev@gmail.com>
https://public-inbox.org/meta/20190704231123.GF20404@szeder.dev/
|
|
We need to ensure the BIN_DETECT (8000 byte) check in
ViewVCS can be handled properly when sending giant
files. Otherwise, EPOLLET won't notify us, again,
and responses can get stuck.
While we're at it, bump up the read-size up to 4096
bytes so we make fewer trips to the kernel.
|
|
Some clients may rely on this for STARTTLS support.
|
|
Before I figured out the long_response API, I figured there'd
be expensive, process-monopolizing commands which admins might
want to disable. Nearly 4 years later, we've never needed it
and running a server without commands such as OVER/XOVER is
unimaginable.
|
|
For users relying on socket activation via service manager (e.g.
systemd) and running multiple service instances (@1, @2),
we need to ensure configuration of the socket is NonBlocking.
Otherwise, service managers such as systemd may clear the
O_NONBLOCK flag for a small window where accept/accept4
blocks:
public-inbox-nntpd@1 |systemd |public-inbox-nntpd@2
--------------------------+----------------+--------------------
F_SETFL,O_NONBLOCK|O_RDWR | | (not running, yet)
|F_SETFL, O_RDWR |
|fork+exec @2... |
accept(...) # blocks! | |(started by systemd)
| |F_SETFL,O_NONBLOCK|O_RDWR
| |accept(...) non-blocking
It's a very small window where O_NONBLOCK can be cleared,
but it exists, and I finally hit it after many years.
|
|
* origin/email-simple-mem:
nntp: reduce syscalls for ARTICLE and BODY
mbox: split header and body processing
mbox: use Email::Simple->new to do in-place modifications
nntp: rework and simplify art_lookup response
|
|
We need to ensure all these subroutines return false on
incomplete.
|