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 4940D1FA10 for ; Mon, 10 Aug 2020 02:12:06 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 05/14] index+xcpdb: improve SIG{INT,TERM,HUP,PIPE} behavior Date: Mon, 10 Aug 2020 02:11:56 +0000 Message-Id: <20200810021205.18909-6-e@yhbt.net> In-Reply-To: <20200810021205.18909-1-e@yhbt.net> References: <20200810021205.18909-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: -index now invokes ->DESTROY like xcpdb does, which is necessary to cleanup $INBOX_DIR/msgmap-XXXXXXX files. We'll also exit with the expected values for various signals by adding 128 as described in -xcpdb now terminates worker processes and xapian-compact(1) invocations when prematurely killed, too. --- lib/PublicInbox/Admin.pm | 29 +++++++++++++++++++++++++---- lib/PublicInbox/Xapcmd.pm | 28 +++++++++++++++++++--------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/PublicInbox/Admin.pm b/lib/PublicInbox/Admin.pm index e42b01e0..af2b3da9 100644 --- a/lib/PublicInbox/Admin.pm +++ b/lib/PublicInbox/Admin.pm @@ -5,14 +5,28 @@ # Unstable internal API package PublicInbox::Admin; use strict; -use warnings; -use Cwd 'abs_path'; -use base qw(Exporter); -our @EXPORT_OK = qw(resolve_repo_dir); +use parent qw(Exporter); +use Cwd qw(abs_path); +use POSIX (); +our @EXPORT_OK = qw(resolve_repo_dir setup_signals); use PublicInbox::Config; use PublicInbox::Inbox; use PublicInbox::Spawn qw(popen_rd); +sub setup_signals { + my ($cb, $arg) = @_; # optional + + # we call exit() here instead of _exit() so DESTROY methods + # get called (e.g. File::Temp::Dir and PublicInbox::Msgmap) + $SIG{INT} = $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = sub { + my ($sig) = @_; + # https://www.tldp.org/LDP/abs/html/exitcodes.html + eval { $cb->($sig, $arg) } if $cb; + $sig = 'SIG'.$sig; + exit(128 + POSIX->$sig); + }; +} + sub resolve_repo_dir { my ($cd, $ver) = @_; my $prefix = defined $cd ? $cd : './'; @@ -185,9 +199,16 @@ invalid indexlevel=$indexlevel (must be `basic', `medium', or `full') die missing_mod_msg($err) ." required for indexlevel=$indexlevel\n"; } +sub index_terminate { + my (undef, $ibx) = @_; # $_[0] = signal name + $ibx->git->cleanup; +} + sub index_inbox { my ($ibx, $im, $opt) = @_; my $jobs = delete $opt->{jobs} if $opt; + local %SIG = %SIG; + setup_signals(\&index_terminate, $ibx); if (ref($ibx) && $ibx->version == 2) { eval { require PublicInbox::V2Writable }; die "v2 requirements not met: $@\n" if $@; diff --git a/lib/PublicInbox/Xapcmd.pm b/lib/PublicInbox/Xapcmd.pm index 714f6859..348621ce 100644 --- a/lib/PublicInbox/Xapcmd.pm +++ b/lib/PublicInbox/Xapcmd.pm @@ -2,8 +2,8 @@ # License: AGPL-3.0+ package PublicInbox::Xapcmd; use strict; -use warnings; use PublicInbox::Spawn qw(which popen_rd nodatacow_dir); +use PublicInbox::Admin qw(setup_signals); use PublicInbox::Over; use PublicInbox::SearchIdx; use File::Temp 0.19 (); # ->newdir @@ -126,6 +126,11 @@ sub same_fs_or_die ($$) { die "$x and $y reside on different filesystems\n"; } +sub kill_pids { + my ($sig, $pids) = @_; + kill($sig, keys %$pids); # pids may be empty +} + sub process_queue { my ($queue, $cb, $opt) = @_; my $max = $opt->{jobs} // scalar(@$queue); @@ -138,6 +143,8 @@ sub process_queue { # run in parallel: my %pids; + local %SIG = %SIG; + setup_signals(\&kill_pids, \%pids); while (@$queue) { while (scalar(keys(%pids)) < $max && scalar(@$queue)) { my $args = shift @$queue; @@ -156,12 +163,6 @@ sub process_queue { } } -sub setup_signals () { - # http://www.tldp.org/LDP/abs/html/exitcodes.html - $SIG{INT} = sub { exit(130) }; - $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = sub { exit(1) }; -} - sub prepare_run { my ($ibx, $opt) = @_; my $tmp = {}; # old shard dir => File::Temp->newdir object or undef @@ -294,6 +295,11 @@ sub progress_pfx ($) { ($p[-1] =~ /\A([0-9]+)/) ? "$p[-2]/$1" : $p[-1]; } +sub kill_compact { # setup_signals callback + my ($sig, $pidref) = @_; + kill($sig, $$pidref) if defined($$pidref); +} + # xapian-compact wrapper sub compact ($$) { my ($args, $opt) = @_; @@ -319,14 +325,18 @@ sub compact ($$) { } $pr->("$pfx `".join(' ', @$cmd)."'\n") if $pr; push @$cmd, $src, $dst; - my $rd = popen_rd($cmd, undef, $rdr); + my ($rd, $pid); + local %SIG = %SIG; + setup_signals(\&kill_compact, \$pid); + ($rd, $pid) = popen_rd($cmd, undef, $rdr); while (<$rd>) { if ($pr) { s/\r/\r$pfx /g; $pr->("$pfx $_"); } } - close $rd or die join(' ', @$cmd)." failed: $?n"; + waitpid($pid, 0); + die "@$cmd failed: \$?=$?\n" if $?; } sub cpdb_loop ($$$;$$) {