]> Sergey Matveev's repositories - public-inbox.git/commitdiff
git: allow async_cat to pass arg to callback
authorEric Wong <e@80x24.org>
Wed, 25 Dec 2019 07:50:35 +0000 (07:50 +0000)
committerEric Wong <e@80x24.org>
Thu, 26 Dec 2019 10:48:19 +0000 (10:48 +0000)
This allows callers to avoid allocating several KB for for every
call to ->async_cat.

lib/PublicInbox/Git.pm
t/git.t

index 9059584086ca57ecfb3411cb2cae12b87cc9496b..af3a5712cf79dec86c90e4f92eb9a2df87a3683e 100644 (file)
@@ -148,16 +148,18 @@ sub read_cat_in_full ($$$) {
 
 sub _cat_async_step ($$$) {
        my ($self, $inflight, $in) = @_;
-       my $cb = shift @$inflight or die 'BUG: inflight empty';
+       my $pair = shift @$inflight or die 'BUG: inflight empty';
+       my ($cb, $arg) = @$pair;
        local $/ = "\n";
        my $head = $in->getline;
-       return eval { $cb->(undef) } if $head =~ / missing$/;
+       $head =~ / missing$/ and return
+               eval { $cb->(undef, undef, undef, undef, $arg) };
 
        $head =~ /^([0-9a-f]{40}) (\S+) ([0-9]+)$/ or
                fail($self, "Unexpected result from async git cat-file: $head");
        my ($oid_hex, $type, $size) = ($1, $2, $3 + 0);
        my $bref = read_cat_in_full($self, $in, $size);
-       eval { $cb->($bref, $oid_hex, $type, $size) };
+       eval { $cb->($bref, $oid_hex, $type, $size, $arg) };
 }
 
 sub cat_async_wait ($) {
@@ -319,15 +321,15 @@ sub cat_async_begin {
        $self->{inflight} = [];
 }
 
-sub cat_async ($$$) {
-       my ($self, $oid, $cb) = @_;
+sub cat_async ($$$;$) {
+       my ($self, $oid, $cb, $arg) = @_;
        my $inflight = $self->{inflight} or die 'BUG: not in async';
        if (scalar(@$inflight) >= MAX_INFLIGHT) {
                _cat_async_step($self, $inflight, $self->{in});
        }
 
        $self->{out}->print($oid, "\n") or fail($self, "write error: $!");
-       push @$inflight, $cb;
+       push(@$inflight, [ $cb, $arg ]);
 }
 
 sub commit_title ($$) {
diff --git a/t/git.t b/t/git.t
index d4694f44c2d98393458a856c7b7dabe502c9acdf..6cfadd085f20d82c46c47c015da870b1e74476e9 100644 (file)
--- a/t/git.t
+++ b/t/git.t
@@ -33,6 +33,27 @@ use_ok 'PublicInbox::Git';
 
        is(${$gcf->cat_file($f)}, $$raw, 'not broken after failures');
        is(${$gcf->cat_file($f)}, $$raw, 'not broken after partial read');
+
+       my $oid = $x[0];
+       my $arg = { 'foo' => 'bar' };
+       my $res = [];
+       my $missing = [];
+       $gcf->cat_async_begin;
+       $gcf->cat_async($oid, sub {
+               my ($bref, $oid_hex, $type, $size, $arg) = @_;
+               $res = [ @_ ];
+       }, $arg);
+       $gcf->cat_async('non-existent', sub {
+               my ($bref, $oid_hex, $type, $size, $arg) = @_;
+               $missing = [ @_ ];
+       }, $arg);
+       $gcf->cat_async_wait;
+       my ($bref, $oid_hex, $type, $size, $arg_res) = @$res;
+       is_deeply([$oid_hex, $type, $size], \@x, 'got expected header');
+       is($arg_res, $arg, 'arg passed to cat_async');
+       is_deeply($raw, $bref, 'blob result matches');
+       is_deeply($missing, [ undef, undef, undef, undef, $arg],
+               'non-existent blob gives expected result');
 }
 
 if (1) {