From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 992F01F5AE; Tue, 20 Jul 2021 08:58:58 +0000 (UTC) Date: Tue, 20 Jul 2021 08:58:58 +0000 From: Eric Wong To: meta@public-inbox.org Cc: Konstantin Ryabitsev Subject: [PATCH] httpd: fix SIGHUP by invalidating cache on reload Message-ID: <20210720085858.GA21082@dcvr> References: <20210719200318.wo4ydjonc3u3ibtu@nitro.local> <20210719204935.GA31835@dcvr> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20210719204935.GA31835@dcvr> List-Id: Eric Wong wrote: > I seem to recall HUP having some trouble with -httpd (and less > so with nntpd/imapd); or at least that's what -daemon(8) manpage > alludes to... -------8<------- Subject: [PATCH] httpd: fix SIGHUP by invalidating cache on reload Since we require separate PublicInbox::HTTPD instances for each listen socket address (in order to support {SERVER_} for PSGI env), the old cache needed to be invalidated on rare app refreshes. SIGHUP has always been broken in -httpd (but not -imapd or -nntpd) due to this cache. Update the daemon documentation and 5.10.1-ize some bits while we're in the area. --- Documentation/public-inbox-daemon.pod | 8 +++++--- script/public-inbox-httpd | 6 ++++-- t/httpd.t | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Documentation/public-inbox-daemon.pod b/Documentation/public-inbox-daemon.pod index ec210efa..f77fc3a9 100644 --- a/Documentation/public-inbox-daemon.pod +++ b/Documentation/public-inbox-daemon.pod @@ -5,13 +5,14 @@ public-inbox-daemon - common usage for public-inbox network daemons =head1 SYNOPSIS public-inbox-httpd + public-inbox-imapd public-inbox-nntpd =head1 DESCRIPTION This manual describes common options and behavior for public-inbox network daemons. Network daemons for public-inbox -provide read-only NNTP and HTTP access to public-inboxes. Write +provide read-only NNTP, IMAP and HTTP access to public-inboxes. Write access to a public-inbox will never be required to run these. These daemons are implemented with a common core using @@ -103,7 +104,7 @@ See L below. =item SIGHUP Reload config files associated with the process. -(FIXME: not tested for -httpd, yet) +(Note: broken for L only in E= 1.6) =item SIGTTIN @@ -188,4 +189,5 @@ License: AGPL-3.0+ L =head1 SEE ALSO -L, L +L, L, +L diff --git a/script/public-inbox-httpd b/script/public-inbox-httpd index b31b896d..7b0ec560 100755 --- a/script/public-inbox-httpd +++ b/script/public-inbox-httpd @@ -4,6 +4,7 @@ # # Standalone HTTP server for public-inbox. use strict; +use v5.10.1; use PublicInbox::Daemon; BEGIN { for (qw(Plack::Builder Plack::Util)) { @@ -14,7 +15,7 @@ BEGIN { require PublicInbox::HTTPD; } -my %httpds; +my %httpds; # per-listen-FD mapping for HTTPD->{env}->{SERVER_} my $app; my $refresh = sub { if (@ARGV) { @@ -37,12 +38,13 @@ my $refresh = sub { sub { $www->call(@_) }; }; } + %httpds = (); # invalidate cache }; PublicInbox::Daemon::run('0.0.0.0:8080', $refresh, sub ($$$) { # post_accept my ($client, $addr, $srv) = @_; my $fd = fileno($srv); - my $h = $httpds{$fd} ||= PublicInbox::HTTPD->new($srv, $app); + my $h = $httpds{$fd} //= PublicInbox::HTTPD->new($srv, $app); PublicInbox::HTTP->new($client, $addr, $h), }); diff --git a/t/httpd.t b/t/httpd.t index 0354a733..849f61bb 100644 --- a/t/httpd.t +++ b/t/httpd.t @@ -32,6 +32,10 @@ Date: Thu, 01 Jan 1970 06:06:06 +0000 nntp EOF }; + my $i2 = create_inbox 'test-2', sub { + my ($im, $ibx) = @_; + $im->add(eml_load('t/plack-qp.eml')) or xbail '->add'; + }; local $ENV{HOME} = $home; my $cmd = [ '-init', $group, $inboxdir, 'http://example.com/', $addr ]; ok(run_script($cmd), 'init ran properly'); @@ -64,6 +68,27 @@ EOF "$http_pfx/$group", "$tmpdir/dumb.git"), 0, 'clone successful'); + # test config reload + my $cfg = "$home/.public-inbox/config"; + open my $fh, '>>', $cfg or xbail "open: $!"; + print $fh <{inboxdir} + address = test-2\@example.com + url = https://example.com/test-2 +EOM + close $fh or xbail "close $!"; + $td->kill('HUP') or BAIL_OUT "failed to kill -httpd: $!"; + tick; # wait for HUP to take effect + my $buf = do { + my $c2 = tcp_connect($sock); + $c2->write("GET /test-2/qp\@example.com/raw HTTP/1.0\r\n\r\n") + or xbail "c2 write: $!"; + local $/; + <$c2> + }; + like($buf, qr!\AHTTP/1\.0 200\b!s, 'got 200 after reload for test-2'); + ok($td->kill, 'killed httpd'); $td->join;