summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
445d206)
We we worked around the default range/termination conditions of
long_response in many cases to reduce calls to SQLite or Xapian.
So continue that trend and become more like the PSGI API
which doesn't force callers to specify an article range or
work inside a loop.
+sub msg_range {
+ my ($self, $beg, $end) = @_;
+ my $dbh = $self->{dbh};
+ my $attr = { Columns => [] };
+ my $mids = $dbh->selectall_arrayref(<<'', $attr, $$beg, $end);
+SELECT num,mid FROM msgmap WHERE num >= ? AND num <= ?
+ORDER BY num ASC
+
+ $$beg = $mids->[-1]->[0] + 1 if @$mids;
+ $mids
+}
+
# only used for mapping external serial numbers (e.g. articles from gmane)
# see scripts/xhdr-num2mid or PublicInbox::Filter::RubyLang for usage
sub mid_set {
# only used for mapping external serial numbers (e.g. articles from gmane)
# see scripts/xhdr-num2mid or PublicInbox::Filter::RubyLang for usage
sub mid_set {
$self->{ng} or return '412 no newsgroup selected';
my $n = 0;
$self->{ng} or return '412 no newsgroup selected';
my $n = 0;
- long_response($self, 0, long_response_limit, sub {
- my ($i) = @_;
+ long_response($self, sub {
my $ary = $self->{ng}->mm->ids_after(\$n);
my $ary = $self->{ng}->mm->ids_after(\$n);
- scalar @$ary or return ($$i = long_response_limit);
+ scalar @$ary or return;
more($self, join("\r\n", @$ary));
more($self, join("\r\n", @$ary));
return '.' unless @srch;
my $prev = 0;
return '.' unless @srch;
my $prev = 0;
- long_response($self, 0, long_response_limit, sub {
- my ($i) = @_;
+ long_response($self, sub {
my $srch = $srch[0];
my $msgs = $srch->query_ts($ts, $prev);
if (scalar @$msgs) {
my $srch = $srch[0];
my $msgs = $srch->query_ts($ts, $prev);
if (scalar @$msgs) {
shift @srch;
if (@srch) { # continue onto next newsgroup
$prev = 0;
shift @srch;
if (@srch) { # continue onto next newsgroup
$prev = 0;
} else { # break out of the long response.
} else { # break out of the long response.
- $$i = long_response_limit;
-sub long_response ($$$$) {
- my ($self, $beg, $end, $cb) = @_;
+sub long_response ($$) {
+ my ($self, $cb) = @_;
die "BUG: nested long response" if $self->{long_res};
my $fd = $self->{fd};
die "BUG: nested long response" if $self->{long_res};
my $fd = $self->{fd};
$self->watch_read(0);
my $t0 = now();
$self->{long_res} = sub {
$self->watch_read(0);
my $t0 = now();
$self->{long_res} = sub {
- # limit our own running time for fairness with other
- # clients and to avoid buffering too much:
- my $lim = $end == long_response_limit ? 1 : 100;
-
- my $err;
- do {
- eval { $cb->(\$beg) };
- } until (($err = $@) || $self->{closed} ||
- ++$beg > $end || !--$lim || $self->{write_buf_size});
-
- if ($err || $self->{closed}) {
+ my $more = eval { $cb->() };
+ if ($@ || $self->{closed}) {
$self->{long_res} = undef;
$self->{long_res} = undef;
err($self,
"%s during long response[$fd] - %0.6f",
err($self,
"%s during long response[$fd] - %0.6f",
}
if ($self->{closed}) {
out($self, " deferred[$fd] aborted - %0.6f",
}
if ($self->{closed}) {
out($self, " deferred[$fd] aborted - %0.6f",
update_idle_time($self);
$self->watch_read(1);
}
update_idle_time($self);
$self->watch_read(1);
}
- } elsif (!$lim || $self->{write_buf_size}) {
+ } elsif ($more) { # $self->{write_buf_size}:
# no recursion, schedule another call ASAP
# but only after all pending writes are done
update_idle_time($self);
# no recursion, schedule another call ASAP
# but only after all pending writes are done
update_idle_time($self);
my $mm = $self->{ng}->mm;
my ($beg, $end) = @$r;
more($self, $xhdr ? r221 : r225);
my $mm = $self->{ng}->mm;
my ($beg, $end) = @$r;
more($self, $xhdr ? r221 : r225);
- long_response($self, $beg, $end, sub {
- my ($i) = @_;
- my $mid = $mm->mid_for($$i);
- more($self, "$$i <$mid>") if defined $mid;
+ long_response($self, sub {
+ my $r = $mm->msg_range(\$beg, $end);
+ @$r or return;
+ more($self, join("\r\n", map {
+ "$_->[0] <$_->[1]>"
+ } @$r));
+ 1;
my $mm = $ng->mm;
my ($beg, $end) = @$r;
more($self, $xhdr ? r221 : r225);
my $mm = $ng->mm;
my ($beg, $end) = @$r;
more($self, $xhdr ? r221 : r225);
- long_response($self, $beg, $end, sub {
- my ($i) = @_;
- my $mid = $mm->mid_for($$i);
- more($self, "$$i ".xref($ng, $$i)) if defined $mid;
+ long_response($self, sub {
+ my $r = $mm->msg_range(\$beg, $end);
+ @$r or return;
+ more($self, join("\r\n", map {
+ # TODO: use $_->[1] (mid) to fill
+ # Xref: from other inboxes
+ my $num = $_->[0];
+ "$num ".xref($ng, $num);
+ } @$r));
+ 1;
my ($beg, $end) = @$r;
more($self, $xhdr ? r221 : r225);
my $cur = $beg;
my ($beg, $end) = @$r;
more($self, $xhdr ? r221 : r225);
my $cur = $beg;
- long_response($self, 0, long_response_limit, sub {
- my ($i) = @_;
+ long_response($self, sub {
my $msgs = $srch->query_xover($cur, $end);
my $msgs = $srch->query_xover($cur, $end);
- my $nr = scalar @$msgs or
- return ($$i = long_response_limit);
+ my $nr = scalar @$msgs or return;
my $tmp = '';
foreach my $s (@$msgs) {
$tmp .= $s->num . ' ' . $s->$field . "\r\n";
my $tmp = '';
foreach my $s (@$msgs) {
$tmp .= $s->num . ' ' . $s->$field . "\r\n";
my $mm = $ng->mm;
my $srch = $ng->search;
more($self, '224 Overview information follows');
my $mm = $ng->mm;
my $srch = $ng->search;
more($self, '224 Overview information follows');
- long_response($self, $beg, $end, sub {
- my ($i) = @_;
- my $num = $$i;
- my $h = search_header_for($srch, $num, 'references');
- defined $h or return;
- more($self, "$num $h");
+
+ long_response($self, sub {
+ my $h = search_header_for($srch, $beg, 'references');
+ more($self, "$beg $h") if defined($h);
+ $beg++ < $end;
more($self, "224 Overview information follows for $beg to $end");
my $srch = $self->{ng}->search;
my $cur = $beg;
more($self, "224 Overview information follows for $beg to $end");
my $srch = $self->{ng}->search;
my $cur = $beg;
- long_response($self, 0, long_response_limit, sub {
- my ($i) = @_;
+ long_response($self, sub {
my $msgs = $srch->query_xover($cur, $end);
my $msgs = $srch->query_xover($cur, $end);
- my $nr = scalar @$msgs or return ($$i = long_response_limit);
+ my $nr = scalar @$msgs or return;
# OVERVIEW.FMT
more($self, join("\r\n", map {
over_line($_->{num}, $_);
} @$msgs));
$cur = $msgs->[-1]->{num} + 1;
# OVERVIEW.FMT
more($self, join("\r\n", map {
over_line($_->{num}, $_);
} @$msgs));
$cur = $msgs->[-1]->{num} + 1;
{
$mime->header_set('Message-Id', '<abcde@1>', '<abcde@2>');
{
$mime->header_set('Message-Id', '<abcde@1>', '<abcde@2>');
+ $mime->header_set('References', '<zz-mid@b>');
ok($im->add($mime), 'message with multiple Message-ID');
$im->done;
my @found;
ok($im->add($mime), 'message with multiple Message-ID');
$im->done;
my @found;
}
is_deeply([sort keys %lg], [sort keys %$x],
'XOVER and LISTGROUPS return the same article numbers');
}
is_deeply([sort keys %lg], [sort keys %$x],
'XOVER and LISTGROUPS return the same article numbers');
+
+ my $xref = $n->xhdr('Xref', '1-');
+ is_deeply([sort keys %lg], [sort keys %$xref], 'Xref range OK');
+
+ my $mids = $n->xhdr('Message-ID', '1-');
+ is_deeply([sort keys %lg], [sort keys %$xref], 'Message-ID range OK');
+
+ my $rover = $n->xrover('1-');
+ is_deeply([sort keys %lg], [sort keys %$rover], 'XROVER range OK');
};
{
local $ENV{NPROC} = 2;
};
{
local $ENV{NPROC} = 2;