]> Sergey Matveev's repositories - public-inbox.git/commitdiff
lei q: do not leave temporary files after oneshot exit
authorEric Wong <e@80x24.org>
Tue, 2 Feb 2021 11:46:55 +0000 (11:46 +0000)
committerEric Wong <e@80x24.org>
Wed, 3 Feb 2021 07:32:39 +0000 (07:32 +0000)
Avoid on-stack shortcuts which may prevent destructors from
firing since we're not inside the event loop.  We'll also tidy
up the unlink mechanism in LeiOverview while we're at it.

lib/PublicInbox/LEI.pm
lib/PublicInbox/LeiOverview.pm
lib/PublicInbox/LeiQuery.pm
lib/PublicInbox/LeiXSearch.pm
xt/lei-sigpipe.t

index d6fa814cf197411ab67abb33415fe79cc5327ce4..44afced306f4722ac0d4ed626010cda5ceea26a1 100644 (file)
@@ -284,20 +284,22 @@ sub x_it ($$) {
        dump_and_clear_log();
        if (my $sock = $self->{sock}) {
                send($sock, "x_it $code", MSG_EOR);
-       } elsif (!$self->{oneshot}) {
-               return; # client disconnected, noop
-       } elsif (my $signum = ($code & 127)) { # usually SIGPIPE (13)
-               $SIG{PIPE} = 'DEFAULT'; # $SIG{$signum} doesn't work
-               kill $signum, $$;
-               sleep; # wait for signal
-       } else {
+       } elsif ($self->{oneshot}) {
                # don't want to end up using $? from child processes
                for my $f (qw(lxs l2m)) {
                        my $wq = delete $self->{$f} or next;
                        $wq->DESTROY;
                }
-               $quit->($code >> 8);
-       }
+               # cleanup anything that has tempfiles
+               delete @$self{qw(ovv dedupe)};
+               if (my $signum = ($code & 127)) { # usually SIGPIPE (13)
+                       $SIG{PIPE} = 'DEFAULT'; # $SIG{$signum} doesn't work
+                       kill $signum, $$;
+                       sleep; # wait for signal
+               } else {
+                       $quit->($code >> 8);
+               }
+       } # else ignore if client disconnected
 }
 
 sub err ($;@) {
index 1d62ffe253d19d8100d70c5782962a4ecd761ccd..31cc67f112efee5db69c7d7abae2f0efbca91a3c 100644 (file)
@@ -26,16 +26,15 @@ sub _iso8601 ($) { strftime('%Y-%m-%dT%H:%M:%SZ', gmtime($_[0])) }
 # we open this in the parent process before ->wq_do handoff
 sub ovv_out_lk_init ($) {
        my ($self) = @_;
-       $self->{tmp_lk_id} = "$self.$$";
        my $tmp = File::Temp->new("lei-ovv.dst.$$.lock-XXXXXX",
                                        TMPDIR => 1, UNLINK => 0);
-       $self->{lock_path} = $tmp->filename;
+       $self->{"lk_id.$self.$$"} = $self->{lock_path} = $tmp->filename;
 }
 
 sub ovv_out_lk_cancel ($) {
        my ($self) = @_;
-       ($self->{tmp_lk_id}//'') eq "$self.$$" and
-               unlink(delete($self->{lock_path}));
+       my $lock_path = delete $self->{"lk_id.$self.$$"} or return;
+       unlink($lock_path);
 }
 
 sub detect_fmt ($$) {
index 7c1e360651e31fec055640af020575dab1b22efa..ca214ca19230c149b1b5b49833cd6283bf8e5e59 100644 (file)
@@ -54,7 +54,7 @@ sub lei_q {
                return $self->fail('no local or remote inboxes to search');
        }
        my $xj = $lxs->concurrency($opt);
-       my $ovv = PublicInbox::LeiOverview->new($self) or return;
+       PublicInbox::LeiOverview->new($self) or return;
        $self->atfork_prepare_wq($lxs);
        $lxs->wq_workers_start('lei_xsearch', $xj, $self->oldset);
        delete $lxs->{-ipc_atfork_child_close};
@@ -90,7 +90,7 @@ sub lei_q {
        # descending docid order
        $mset_opt{relevance} //= -2 if $opt->{thread};
        $self->{mset_opt} = \%mset_opt;
-       $ovv->ovv_begin($self);
+       $self->{ovv}->ovv_begin($self);
        $lxs->do_query($self);
 }
 
index e997431f1e5521f657cbf284b97f48e6e5199845..b3cace74916cd442ffb19ea5a3b1d89feb78b760 100644 (file)
@@ -387,8 +387,9 @@ sub query_prepare { # called by wq_do
 
 sub fail_handler ($;$$) {
        my ($lei, $code, $io) = @_;
-       if (my $lxs = delete $lei->{lxs}) {
-               $lxs->wq_wait_old($lei) if $lxs->wq_kill_old; # lei-daemon
+       for my $f (qw(lxs l2m)) {
+               my $wq = delete $lei->{$f} or next;
+               $wq->wq_wait_old($lei) if $wq->wq_kill_old; # lei-daemon
        }
        close($io) if $io; # needed to avoid warnings on SIGPIPE
        $lei->x_it($code // (1 >> 8));
index 1aa9ed079ae19ac1307899e20a07e94d7ee5b7c9..ba2d23c87e1cff3db195dee3780ca619192d4c86 100644 (file)
@@ -29,7 +29,30 @@ my $do_test = sub {
        }
 };
 
-$do_test->();
-$do_test->({XDG_RUNTIME_DIR => '/dev/null'});
+my ($tmp, $for_destroy) = tmpdir();
+my $pid;
+my $opt = { run_mode => 0, 1 => \(my $out = '') };
+if (run_script([qw(lei daemon-pid)], undef, $opt)) {
+       chomp($pid = $out);
+       mkdir "$tmp/d" or BAIL_OUT $!;
+       local $ENV{TMPDIR} = "$tmp/d";
+       $do_test->();
+       $out = '';
+       ok(run_script([qw(lei daemon-pid)], undef, $opt), 'daemon-pid again');
+       chomp($out);
+       is($out, $pid, 'daemon-pid unchanged');
+       ok(kill(0, $pid), 'daemon still running');
+       $out = '';
+}
+{
+       mkdir "$tmp/1" or BAIL_OUT $!;
+       local $ENV{TMPDIR} = "$tmp/1";
+       $do_test->({XDG_RUNTIME_DIR => '/dev/null'});
+       is(unlink(glob("$tmp/1/*")), 0, 'nothing left over w/ oneshot');
+}
+
+# the one-shot test should be slow enough that the daemon has cleaned
+# up in the background:
+is_deeply([glob("$tmp/d/*")], [], 'nothing left over with daemon');
 
 done_testing;