_do_enquire($self, $qtid, $opts);
}
-sub _do_enquire {
- my ($self, $query, $opts) = @_;
+sub retry_reopen {
+ my ($self, $cb) = @_;
my $ret;
for (1..10) {
- eval { $ret = _enquire_once($self, $query, $opts) };
+ eval { $ret = $cb->() };
return $ret unless $@;
# Exception: The revision being read has been discarded -
# you should call Xapian::Database::reopen()
- if (index($@, 'Xapian::Database::reopen') >= 0) {
+ if (ref($@) eq 'Search::Xapian::DatabaseModifiedError') {
reopen($self);
} else {
- die $@;
+ die;
}
}
}
+sub _do_enquire {
+ my ($self, $query, $opts) = @_;
+ retry_reopen($self, sub { _enquire_once($self, $query, $opts) });
+}
+
sub _enquire_once {
my ($self, $query, $opts) = @_;
my $enquire = $self->enquire;
PublicInbox::WwwStream->response($ctx, $code, $cb);
}
+# allow undef for individual doc loads...
+sub load_doc_retry {
+ my ($srch, $mitem) = @_;
+
+ eval {
+ $srch->retry_reopen(sub {
+ PublicInbox::SearchMsg->load_doc($mitem->get_document)
+ });
+ }
+}
+
# display non-threaded search results similar to what users expect from
# regular WWW search engines:
sub mset_summary {
my $pad = length("$total");
my $pfx = ' ' x $pad;
my $res = \($ctx->{-html_tip});
+ my $srch = $ctx->{srch};
foreach my $m ($mset->items) {
my $rank = sprintf("%${pad}d", $m->get_rank + 1);
my $pct = $m->get_percent;
- my $smsg = PublicInbox::SearchMsg->load_doc($m->get_document);
+ my $smsg = load_doc_retry($srch, $m);
+ unless ($smsg) {
+ eval {
+ $m = "$m ".$m->get_docid . " expired\n";
+ $ctx->{env}->{'psgi.errors'}->print($m);
+ };
+ next;
+ }
my $s = ascii_html($smsg->subject);
my $f = ascii_html($smsg->from_name);
my $ts = PublicInbox::View::fmt_ts($smsg->ts);
sub mset_thread {
my ($ctx, $mset, $q) = @_;
my %pct;
- my @m = map {
+ my $msgs = $ctx->{srch}->retry_reopen(sub { [ map {
my $i = $_;
- my $m = PublicInbox::SearchMsg->load_doc($i->get_document);
- $pct{$m->mid} = $i->get_percent;
- $m;
- } ($mset->items);
+ my $smsg = PublicInbox::SearchMsg->load_doc($i->get_document);
+ $pct{$smsg->mid} = $i->get_percent;
+ $smsg;
+ } ($mset->items) ]});
- my $th = PublicInbox::SearchThread->new(\@m);
+ my $th = PublicInbox::SearchThread->new($msgs);
$th->thread;
if ($q->{r}) { # order by relevance
$th->order(sub {
$ctx->{prev_attr} = '';
$ctx->{prev_level} = 0;
$ctx->{seen} = {};
- $ctx->{s_nr} = scalar(@m).'+ results';
+ $ctx->{s_nr} = scalar(@$msgs).'+ results';
PublicInbox::View::walk_thread($th, $ctx,
*PublicInbox::View::pre_thread);
- my $msgs = \@m;
my $mime;
sub {
return unless $msgs;
my $ibx = $ctx->{-inbox};
my @items = $mset->items;
$ctx->{search_query} = $q;
+ my $srch = $ctx->{srch};
PublicInbox::WwwAtomStream->response($ctx, 200, sub {
while (my $x = shift @items) {
- $x = PublicInbox::SearchMsg->load_doc($x->get_document);
+ $x = load_doc_retry($srch, $x);
$x = $ibx->msg_by_smsg($x) and
return Email::MIME->new($x);
}
sub thread_html {
my ($ctx) = @_;
my $mid = $ctx->{mid};
- my $sres = $ctx->{srch}->get_thread($mid);
- my $msgs = load_results($sres);
+ my $srch = $ctx->{srch};
+ my $sres = $srch->get_thread($mid);
+ my $msgs = load_results($srch, $sres);
my $nr = $sres->{total};
return missing_thread($ctx) if $nr == 0;
my $skel = '<hr><pre>';
$ctx->{prev_attr} = '';
$ctx->{prev_level} = 0;
$ctx->{dst} = $dst;
- walk_thread(thread_results(load_results($sres)), $ctx, *skel_dump);
+ $sres = load_results($srch, $sres);
+ walk_thread(thread_results($sres), $ctx, *skel_dump);
$ctx->{parent_msg} = $parent;
}
}
sub load_results {
- my ($sres) = @_;
-
- [ map { $_->ensure_metadata; $_ } @{delete $sres->{msgs}} ];
+ my ($srch, $sres) = @_;
+ my $msgs = delete $sres->{msgs};
+ $srch->retry_reopen(sub { [ map { $_->ensure_metadata; $_ } @$msgs ] });
}
sub msg_timestamp {
my $opts = { offset => $off, limit => 200 };
$ctx->{order} = [];
- my $sres = $ctx->{srch}->query('', $opts);
+ my $srch = $ctx->{srch};
+ my $sres = $srch->query('', $opts);
my $nr = scalar @{$sres->{msgs}};
if ($nr) {
- $sres = load_results($sres);
+ $sres = load_results($srch, $sres);
walk_thread(thread_results($sres), $ctx, *acc_topic);
}
$ctx->{-next_o} = $off+ $nr;