git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2] fetch-pack: do not reset in_vain on non-novel acks

From
JTJonathan Tan <jonathantanmy@google.com>
Date
Sep 23, 2016, 17:41 UTC
Message-ID
<1474652495-26051-1-git-send-email-jonathantanmy@google.com>
In-Reply-To
<xmqqfuor4s4z.fsf@gitster.mtv.corp.google.com>

The MAX_IN_VAIN mechanism was introduced in commit f061e5f ("fetch-pack: give up after getting too many "ack continue"", 2006-05-24) to stop ref negotiation if a number of consecutive "have"s have been sent with no corresponding new acks. This is to stop the client from digging too deep in an irrelevant side branch in vain without ever finding a common ancestor. A use case (as described in that commit) is the scenario in which the local repository has more roots than the remote repository.

However, during a negotiation in which stateless RPCs are used, MAX_IN_VAIN will (almost) never trigger (in the more-roots scenario above and others) because in each new request, the client has to inform the server of objects it already has and knows the server has (to remind the server of the state), which the server then acks.

Make fetch-pack only consider, as new acks for the purpose of MAX_IN_VAIN, acks for objects for which the client has never received an ack before in this session.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---
Thanks for your comments - I really appreciate them.
Update from original:
o removed redundant text from commit message and comment in patch
o mentioned stopping the client from digging too deep in the commit
  message

I tried looking at creating a helper function to reduce both the size and the nesting level of the loop, but it seems to me that a helper function can't be extracted so easily because the logic is quite intertwined with the rest of the function. For example, the "if (args->stateless_rpc..." block uses 6 variables from the outer scope: args, ack, commit, result_sha1, req_buf, and state_len (and in_vain, but this can be the return value of the function). Expanding it wider would allow us to make some of those 6 local, but also introduce new ones from the outer scope.

 fetch-pack.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/fetch-pack.c b/fetch-pack.c
index 85e77af..413937e 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -428,10 +428,17 @@ static int find_common(struct fetch_pack_args *args,
 						const char *hex = sha1_to_hex(result_sha1);
 						packet_buf_write(&req_buf, "have %s\n", hex);
 						state_len = req_buf.len;
-					}
+						/*
+						 * Reset in_vain because an ack
+						 * for this commit has not been
+						 * seen.
+						 */
+						in_vain = 0;
+					} else if (!args->stateless_rpc
+						   || ack != ACK_common)
+						in_vain = 0;
 					mark_common(commit, 0, 1);
 					retval = 0;
-					in_vain = 0;
 					got_continue = 1;
 					if (ack == ACK_ready) {
 						clear_prio_queue(&rev_list);
-- 
2.8.0.rc3.226.g39d4020
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 6 in “do not reset in_vain on non-novel acks”
  1. do not reset in_vain on non-novel acksJonathan Tan, Sep 22, 2016
  2. fetch-pack: do not reset in_vain on non-novel acksJonathan Tan, Sep 22, 2016
  3. Junio C HamanoSep 22, 2016
  4. fetch-pack: do not reset in_vain on non-novel acksJonathan Tan, Sep 23, 2016
  5. Junio C HamanoSep 23, 2016
  6. Junio C HamanoSep 22, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.