public-inbox.git  about / heads / tags
an "archives first" approach to mailing lists
blob ac25eece44f8870626c5ff8ad3044864a678b512 1459 bytes (raw)
$ git show HEAD:lib/PublicInbox/XhcMset.pm	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 
# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>

# mocks Xapian::Mset and allows slow queries from blocking the event loop
package PublicInbox::XhcMset;
use v5.12;
use parent qw(PublicInbox::DS);
use PublicInbox::XhcMsetIterator;
use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT);

sub event_step {
	my ($self) = @_;
	my ($cb, @args) = @{delete $self->{cb_args} // return};
	my $rd = $self->{sock};
	eval {
		my $hdr = <$rd> // die "E: reading mset header: $!";
		for (split /\s+/, $hdr) { # read mset.size + estimated_matches
			my ($k, $v) = split /=/, $_, 2;
			$k =~ s/\A[^\.]*\.//; # s/(mset)?\./
			$self->{$k} = $v;
		}
		my $size = $self->{size} // die "E: bad xhc header: `$hdr'";
		my @it = map { PublicInbox::XhcMsetIterator::make($_) } <$rd>;
		$self->{items} = \@it;
		scalar(@it) == $size or die
			'E: got ',scalar(@it),", expected mset.size=$size";
	};
	my $err = $@;
	$self->close;
	eval { $cb->(@args, $self, $err) };
	warn "E: $@\n" if $@;
}

sub maybe_new {
	my (undef, $rd, $srch, @cb_args) = @_;
	my $self = bless { cb_args => \@cb_args, srch => $srch }, __PACKAGE__;
	if ($PublicInbox::DS::in_loop) { # async
		$self->SUPER::new($rd, EPOLLIN|EPOLLONESHOT);
	} else { # synchronous
		$self->{sock} = $rd;
		event_step($self);
		undef;
	}
}

eval(join('', map { "sub $_ { \$_[0]->{$_} }\n" } qw(size
	get_matches_estimated)));

sub items { @{$_[0]->{items}} }

1;

git clone https://public-inbox.org/public-inbox.git
git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git