- delete($ibx->{$_}) for (qw(mm over search)); # cleanup
- process_queue(\@q, $cb, $max, $opt);
- commit_changes($ibx, $tmp, $opt);
- });
+sub _run { # with_umask callback
+ my ($ibx, $cb, $opt) = @_;
+ my $im = $ibx->can('importer') ? $ibx->importer(0) : undef;
+ ($im // $ibx)->lock_acquire;
+ my ($tmp, $queue) = prepare_run($ibx, $opt);
+
+ # fine-grained locking if we prepare for reindex
+ if (!$opt->{-coarse_lock}) {
+ prepare_reindex($ibx, $opt);
+ ($im // $ibx)->lock_release;
+ }
+
+ $ibx->cleanup if $ibx->can('cleanup');
+ process_queue($queue, $cb, $opt);
+ ($im // $ibx)->lock_acquire if !$opt->{-coarse_lock};
+ commit_changes($ibx, $im, $tmp, $opt);
+}
+
+sub run {
+ my ($ibx, $task, $opt) = @_; # task = 'cpdb' or 'compact'
+ my $cb = \&$task;
+ PublicInbox::Admin::progress_prepare($opt ||= {});
+ my $dir;
+ for my $fld (qw(inboxdir topdir)) {
+ my $d = $ibx->{$fld} // next;
+ -d $d or die "$fld=$d does not exist\n";
+ $dir = $d;
+ last;
+ }
+ check_compact() if $opt->{compact} && $ibx->search;
+
+ if (!$ibx->can('eidx_sync') && !$opt->{-coarse_lock}) {
+ # per-epoch ranges for v2
+ # v1:{ from => $OID }, v2:{ from => [ $OID, $OID, $OID ] } }
+ $opt->{reindex} = { from => $ibx->version == 1 ? '' : [] };
+ PublicInbox::SearchIdx::load_xapian_writable();
+ }
+
+ local @SIG{keys %SIG} = values %SIG;
+ setup_signals();
+ $ibx->with_umask(\&_run, $ibx, $cb, $opt);