From 5c94a55c24a17c8250cf80d78246851c0a7c4087 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 25 Dec 2019 07:50:35 +0000 Subject: git: allow async_cat to pass arg to callback This allows callers to avoid allocating several KB for for every call to ->async_cat. --- lib/PublicInbox/Git.pm | 14 ++++++++------ t/git.t | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm index 90595840..af3a5712 100644 --- a/lib/PublicInbox/Git.pm +++ b/lib/PublicInbox/Git.pm @@ -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 d4694f44..6cfadd08 100644 --- 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) { -- cgit v1.2.3-24-ge0c7