about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2020-10-16 06:59:33 +0000
committerEric Wong <e@80x24.org>2020-10-16 17:15:24 +0000
commit2484555ea1a2b5d0af4be5840a92605d9dbb7930 (patch)
treee6a5cfab89947f9dd0a160c90572b6e6377f1157 /lib
parentaaae95b1f3be705daf815b490ec556bdf19e0538 (diff)
downloadpublic-inbox-2484555ea1a2b5d0af4be5840a92605d9dbb7930.tar.gz
For external indices, we'll need to support nested cat_async
invocations to deduplicate cross-posted messages.

Thus we need to ensure we do not clobber the {inflight*} queues
while stepping through and ensure {cat_rbuf} is stored before
invoking callbacks.

This fixes the ->cat_async-only case, but does not yet
account for the mix of ->check_async interspersed with
->cat_async calls, yet.  More work will be needed on that
front at a later date.
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/Git.pm14
1 files changed, 9 insertions, 5 deletions
diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index 449223ec..eb5de159 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -204,14 +204,14 @@ sub cat_async_step ($$) {
         } else {
                 $self->fail("Unexpected result from async git cat-file: $head");
         }
-        eval { $cb->($bref, $oid, $type, $size, $arg) };
         $self->{cat_rbuf} = $rbuf if $$rbuf ne '';
+        eval { $cb->($bref, $oid, $type, $size, $arg) };
         warn "E: $oid: $@\n" if $@;
 }
 
 sub cat_async_wait ($) {
         my ($self) = @_;
-        my $inflight = delete $self->{inflight} or return;
+        my $inflight = $self->{inflight} or return;
         while (scalar(@$inflight)) {
                 cat_async_step($self, $inflight);
         }
@@ -251,14 +251,14 @@ sub check_async_step ($$) {
                 my $ret = my_read($self->{in_c}, $rbuf, $type + 1);
                 fail($self, defined($ret) ? 'read EOF' : "read: $!") if !$ret;
         }
+        $self->{chk_rbuf} = $rbuf if $$rbuf ne '';
         eval { $cb->($hex, $type, $size, $arg, $self) };
         warn "E: check($req) $@\n" if $@;
-        $self->{chk_rbuf} = $rbuf if $$rbuf ne '';
 }
 
 sub check_async_wait ($) {
         my ($self) = @_;
-        my $inflight_c = delete $self->{inflight_c} or return;
+        my $inflight_c = $self->{inflight_c} or return;
         while (scalar(@$inflight_c)) {
                 check_async_step($self, $inflight_c);
         }
@@ -318,13 +318,15 @@ sub _destroy {
 
 sub cat_async_abort ($) {
         my ($self) = @_;
-        if (my $inflight = delete $self->{inflight}) {
+        if (my $inflight = $self->{inflight}) {
                 while (@$inflight) {
                         my ($req, $cb, $arg) = splice(@$inflight, 0, 3);
                         $req =~ s/ .*//; # drop git_dir for Gcf2Client
                         eval { $cb->(undef, $req, undef, undef, $arg) };
                         warn "E: $req: $@ (in abort)\n" if $@;
                 }
+                delete $self->{cat_rbuf};
+                delete $self->{inflight};
         }
         cleanup($self);
 }
@@ -357,6 +359,8 @@ sub cleanup {
         delete $self->{async_cat};
         check_async_wait($self);
         cat_async_wait($self);
+        delete $self->{inflight};
+        delete $self->{inflight_c};
         _destroy($self, qw(cat_rbuf in out pid));
         _destroy($self, qw(chk_rbuf in_c out_c pid_c err_c));
         !!($self->{pid} || $self->{pid_c});