Re: [PATCH 2/6] fetch-pack: truly stop negotiation upon ACK ready

2018-06-05 Thread Jonathan Tan
On Tue, 5 Jun 2018 16:16:34 -0700
Jonathan Nieder  wrote:

> Hi,
> 
> Jonathan Tan wrote:
> 
> > When "ACK %s ready" is received, find_common() clears rev_list in an
> > attempt to stop further "have" lines from being sent [1]. This appears
> > to work, despite the invocation to mark_common() in the "while" loop.
> 
> Does "appears to work" mean "works" or "doesn't work but does an okay
> job of faking"?

"Appears to work" means I think that it works, but I don't think I can
conclusively prove it.

> > Though it is possible for mark_common() to invoke rev_list_push() (thus
> > making rev_list non-empty once more), it is more likely that the commits
> 
> nit: s/more likely/most likely/
> or s/it is more likely that/usually/
> 
> > in rev_list that have un-SEEN parents are also unparsed, meaning that
> > mark_common() is not invoked on them.
> >
> > To avoid all this uncertainty, it is better to explicitly end the loop
> > when "ACK %s ready" is received instead of clearing rev_list. Remove the
> > clearing of rev_list and write "if (got_ready) break;" instead.
> 
> I'm still a little curious about whether this can happen in practice
> or whether it's just about readability (or whether you didn't figure
> out which, which is perfectly fine), but either way it's a good
> change.

I tried to figure out which, but concluded that I can't.

I think that in v2's commit message, I'll start with describing the
readability aspect.

> > @@ -1281,7 +1281,6 @@ static int process_acks(struct packet_reader *reader, 
> > struct oidset *common)
> > }
> >  
> > if (!strcmp(reader->line, "ready")) {
> > -   clear_prio_queue(_list);
> > received_ready = 1;
> > continue;
> 
> I'm curious about the lifetime of _list.  Does the priority queue
> get freed eventually?

No (which potentially causes a problem in the case that fetch-pack is
invoked twice), but I fix that in patch 4/6, so I didn't bother
addressing it here. I'll add a note about the lifetime of this priority
queue in v2.


Re: [PATCH 2/6] fetch-pack: truly stop negotiation upon ACK ready

2018-06-05 Thread Jonathan Nieder
Jonathan Nieder wrote:
> Jonathan Tan wrote:

>> The corresponding code for protocol v2 in process_acks() does not have
>> the same problem, because the invoker of process_acks()
>> (do_fetch_pack_v2()) proceeds immediately to processing the packfile
>
> nit: s/proceeds/procedes/

Whoops.  My spellchecker deceived me.

I even checked Wiktionary and found that it was a verb there and didn't
bother to look at the definition:

Misspelling of proceed

You already had the right spelling.

Sorry for the noise,
Jonathan


Re: [PATCH 2/6] fetch-pack: truly stop negotiation upon ACK ready

2018-06-05 Thread Jonathan Nieder
Hi,

Jonathan Tan wrote:

> When "ACK %s ready" is received, find_common() clears rev_list in an
> attempt to stop further "have" lines from being sent [1]. This appears
> to work, despite the invocation to mark_common() in the "while" loop.

Does "appears to work" mean "works" or "doesn't work but does an okay
job of faking"?

> Though it is possible for mark_common() to invoke rev_list_push() (thus
> making rev_list non-empty once more), it is more likely that the commits

nit: s/more likely/most likely/
or s/it is more likely that/usually/

> in rev_list that have un-SEEN parents are also unparsed, meaning that
> mark_common() is not invoked on them.
>
> To avoid all this uncertainty, it is better to explicitly end the loop
> when "ACK %s ready" is received instead of clearing rev_list. Remove the
> clearing of rev_list and write "if (got_ready) break;" instead.

I'm still a little curious about whether this can happen in practice
or whether it's just about readability (or whether you didn't figure
out which, which is perfectly fine), but either way it's a good
change.

> The corresponding code for protocol v2 in process_acks() does not have
> the same problem, because the invoker of process_acks()
> (do_fetch_pack_v2()) proceeds immediately to processing the packfile

nit: s/proceeds/procedes/

> upon "ACK %s ready". The clearing of rev_list here is thus redundant,
> and this patch also removes it.
>
> [1] The rationale is further described in the originating commit
> f2cba9299b ("fetch-pack: Finish negotation if remote replies "ACK %s
> ready"", 2011-03-14).
>
> Signed-off-by: Jonathan Tan 
> ---
>  fetch-pack.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
[...]
> +++ b/fetch-pack.c
> @@ -517,10 +517,8 @@ static int find_common(struct fetch_pack_args *args,
>   mark_common(commit, 0, 1);
>   retval = 0;
>   got_continue = 1;
> - if (ack == ACK_ready) {
> - clear_prio_queue(_list);
> + if (ack == ACK_ready)
>   got_ready = 1;
> - }
>   break;
>   }
>   }
> @@ -530,6 +528,8 @@ static int find_common(struct fetch_pack_args *args,
>   print_verbose(args, _("giving up"));
>   break; /* give up */
>   }
> + if (got_ready)
> + break;

Makes sense.

> @@ -1281,7 +1281,6 @@ static int process_acks(struct packet_reader *reader, 
> struct oidset *common)
>   }
>  
>   if (!strcmp(reader->line, "ready")) {
> - clear_prio_queue(_list);
>   received_ready = 1;
>   continue;

I'm curious about the lifetime of _list.  Does the priority queue
get freed eventually?

Thanks,
Jonathan


[PATCH 2/6] fetch-pack: truly stop negotiation upon ACK ready

2018-06-04 Thread Jonathan Tan
When "ACK %s ready" is received, find_common() clears rev_list in an
attempt to stop further "have" lines from being sent [1]. This appears
to work, despite the invocation to mark_common() in the "while" loop.
Though it is possible for mark_common() to invoke rev_list_push() (thus
making rev_list non-empty once more), it is more likely that the commits
in rev_list that have un-SEEN parents are also unparsed, meaning that
mark_common() is not invoked on them.

To avoid all this uncertainty, it is better to explicitly end the loop
when "ACK %s ready" is received instead of clearing rev_list. Remove the
clearing of rev_list and write "if (got_ready) break;" instead.

The corresponding code for protocol v2 in process_acks() does not have
the same problem, because the invoker of process_acks()
(do_fetch_pack_v2()) proceeds immediately to processing the packfile
upon "ACK %s ready". The clearing of rev_list here is thus redundant,
and this patch also removes it.

[1] The rationale is further described in the originating commit
f2cba9299b ("fetch-pack: Finish negotation if remote replies "ACK %s
ready"", 2011-03-14).

Signed-off-by: Jonathan Tan 
---
 fetch-pack.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fetch-pack.c b/fetch-pack.c
index 1358973a4..2d090f612 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -517,10 +517,8 @@ static int find_common(struct fetch_pack_args *args,
mark_common(commit, 0, 1);
retval = 0;
got_continue = 1;
-   if (ack == ACK_ready) {
-   clear_prio_queue(_list);
+   if (ack == ACK_ready)
got_ready = 1;
-   }
break;
}
}
@@ -530,6 +528,8 @@ static int find_common(struct fetch_pack_args *args,
print_verbose(args, _("giving up"));
break; /* give up */
}
+   if (got_ready)
+   break;
}
}
 done:
@@ -1281,7 +1281,6 @@ static int process_acks(struct packet_reader *reader, 
struct oidset *common)
}
 
if (!strcmp(reader->line, "ready")) {
-   clear_prio_queue(_list);
received_ready = 1;
continue;
}
-- 
2.17.0.768.g1526ddbba1.dirty