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-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 204151F5AE for ; Mon, 15 Jun 2020 07:43:17 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] imap: improve IDLE handling at graceful shutdown Date: Mon, 15 Jun 2020 07:43:17 +0000 Message-Id: <20200615074317.22249-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Since IMAP IDLE users aren't expected to issue any commands, we can terminate their connections immediately on graceful shutdown. Furthermore, we need to drop the inotify FD from the epoll set to avoid warnings during global destruction. Embarassingly, this required fixing wacky test ordering from 2a717d13f10fcdc6 ("nntpd+imapd: detect replaced over.sqlite3") --- lib/PublicInbox/IMAP.pm | 4 ++++ lib/PublicInbox/InboxIdle.pm | 4 ++++ t/nntpd.t | 34 ++++++++++++++++------------------ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index 9ae7c60e..d4ef6efe 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -1462,6 +1462,10 @@ sub cmd_starttls ($$) { # for graceful shutdown in PublicInbox::Daemon: sub busy { my ($self, $now) = @_; + if (defined($self->{-idle_tag})) { + $self->write(\"* BYE server shutting down\r\n"); + return; # not busy anymore + } ($self->{rbuf} || $self->{wbuf} || $self->not_idle_long($now)); } diff --git a/lib/PublicInbox/InboxIdle.pm b/lib/PublicInbox/InboxIdle.pm index d60d4f23..d0bb43c5 100644 --- a/lib/PublicInbox/InboxIdle.pm +++ b/lib/PublicInbox/InboxIdle.pm @@ -79,4 +79,8 @@ sub event_step { warn "$self->{inot}->poll err: $@\n" if $@; } +# for graceful shutdown in PublicInbox::Daemon, +# just ensure the FD gets closed ASAP and subscribers +sub busy { 0 } + 1; diff --git a/t/nntpd.t b/t/nntpd.t index d6042d18..b24720eb 100644 --- a/t/nntpd.t +++ b/t/nntpd.t @@ -316,23 +316,6 @@ Date: Fri, 02 Oct 1993 00:00:00 +0000 my @xap = grep m!Search/Xapian!, @of; is_deeply(\@xap, [], 'Xapian not loaded in nntpd'); } - { - setsockopt($s, IPPROTO_TCP, TCP_NODELAY, 1); - syswrite($s, 'HDR List-id 1-'); - select(undef, undef, undef, 0.15); - ok($td->kill, 'killed nntpd'); - select(undef, undef, undef, 0.15); - syswrite($s, "\r\n"); - $buf = ''; - do { - sysread($s, $buf, 4096, length($buf)); - } until ($buf =~ /\r\n\z/); - my @r = split("\r\n", $buf); - like($r[0], qr/^5\d\d /, - 'got 5xx response for unoptimized HDR'); - is(scalar @r, 1, 'only one response line'); - } - # -compact requires Xapian SKIP: { require_mods('Search::Xapian', 2); @@ -356,7 +339,22 @@ Date: Fri, 02 Oct 1993 00:00:00 +0000 my @of = xqx([$lsof, '-p', $td->{pid}], undef, $noerr); is(scalar(grep(/\(deleted\)/, @of)), 0, 'no deleted files'); }; - + { + setsockopt($s, IPPROTO_TCP, TCP_NODELAY, 1); + syswrite($s, 'HDR List-id 1-'); + select(undef, undef, undef, 0.15); + ok($td->kill, 'killed nntpd'); + select(undef, undef, undef, 0.15); + syswrite($s, "\r\n"); + $buf = ''; + do { + sysread($s, $buf, 4096, length($buf)); + } until ($buf =~ /\r\n\z/); + my @r = split("\r\n", $buf); + like($r[0], qr/^5\d\d /, + 'got 5xx response for unoptimized HDR'); + is(scalar @r, 1, 'only one response line'); + } $n = $s = undef; $td->join; is($?, 0, 'no error in exited process');