about summary refs log tree commit homepage
path: root/lib/PublicInbox/Xapcmd.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-05-23 09:36:59 +0000
committerEric Wong <e@80x24.org>2019-05-23 17:43:50 +0000
commited52051030b89985a1ec032ed4acc74912b0dd80 (patch)
treeb72c0b5552eed95f3c62956812d9724423a2895c /lib/PublicInbox/Xapcmd.pm
parent3e894f400e588246f529dd4fb1257e19e63a17ed (diff)
downloadpublic-inbox-ed52051030b89985a1ec032ed4acc74912b0dd80.tar.gz
Cleanup temporary directories on common termination signals
(INT, HUP, PIPE, TERM), but only if it's not in the process
of being committed via rename() sequence.
Diffstat (limited to 'lib/PublicInbox/Xapcmd.pm')
-rw-r--r--lib/PublicInbox/Xapcmd.pm39
1 files changed, 37 insertions, 2 deletions
diff --git a/lib/PublicInbox/Xapcmd.pm b/lib/PublicInbox/Xapcmd.pm
index 0e448047..06389dd0 100644
--- a/lib/PublicInbox/Xapcmd.pm
+++ b/lib/PublicInbox/Xapcmd.pm
@@ -31,13 +31,15 @@ sub commit_changes ($$$) {
                         $over->connect->sqlite_backup_to_file($tmp_over);
                         $over = undef;
                 }
+                chmod($st[2] & 07777, $new) or die "chmod $old: $!\n";
 
+                # Xtmpdir->DESTROY won't remove $new after this:
                 rename($old, "$new/old") or die "rename $old => $new/old: $!\n";
-                chmod($st[2] & 07777, $new) or die "chmod $old: $!\n";
                 rename($new, $old) or die "rename $new => $old: $!\n";
                 my $prev = "$old/old";
                 remove_tree($prev) or die "failed to remove $prev: $!\n";
         }
+        $tmp->done;
         if ($reindex) {
                 $opt->{-skip_lock} = 1;
                 PublicInbox::Admin::index_inbox($ibx, $opt);
@@ -126,7 +128,7 @@ sub run {
         my $old = $ibx->search->xdir(1);
         -d $old or die "$old does not exist\n";
 
-        my $tmp = {}; # old partition => new (tmp) partition
+        my $tmp = PublicInbox::Xtmpdirs->new;
         my $v = $ibx->{version} ||= 1;
         my @cmds;
 
@@ -286,4 +288,37 @@ sub cpdb {
         remove_tree($tmp) or die "failed to remove $tmp: $!\n";
 }
 
+# slightly easier-to-manage manage than END{} blocks
+package PublicInbox::Xtmpdirs;
+use strict;
+use warnings;
+use File::Path qw(remove_tree);
+my %owner;
+
+sub new {
+        # http://www.tldp.org/LDP/abs/html/exitcodes.html
+        $SIG{INT} = sub { exit(130) };
+        $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = sub { exit(1) };
+        my $self = bless {}, $_[0]; # old partition => new (tmp) partition
+        $owner{"$self"} = $$;
+        $self;
+}
+
+sub done {
+        my ($self) = @_;
+        delete $owner{"$self"};
+        $SIG{INT} = $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = 'DEFAULT';
+        %$self = ();
+}
+
+sub DESTROY {
+        my ($self) = @_;
+        my $owner_pid = delete $owner{"$self"} or return;
+        return if $owner_pid != $$;
+        foreach my $new (values %$self) {
+                remove_tree($new) unless -d "$new/old";
+        }
+        $SIG{INT} = $SIG{HUP} = $SIG{PIPE} = $SIG{TERM} = 'DEFAULT';
+}
+
 1;