git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] upload-pack keepalive
@ 2013-09-08  8:59 Jeff King
  2013-09-08  9:01 ` [PATCH 1/2] upload-pack: send keepalive packets during pack computation Jeff King
  2013-09-08  9:02 ` [PATCH 2/2] upload-pack: bump keepalive default to 5 seconds Jeff King
  0 siblings, 2 replies; 4+ messages in thread
From: Jeff King @ 2013-09-08  8:59 UTC (permalink / raw)
  To: git

I've gotten complaints that cloning from github.com with "-q" will
sometimes abort before sending any data. The problem is that during a
quiet clone, upload-pack may be silent for a long time while preparing
the pack (i.e., the "counting objects" and "compressing" phases).

We have load balancers and reverse proxies sitting in front of the git
machines, and these machines may sometimes think the connection has hung
and drop it, even though if they had waited a few more seconds, the pack
would have started coming.

We mitigated it somewhat by bumping the timeouts on our side, but that's
only one piece of the puzzle. Clients may be going through http proxies
or stateful firewalls on their end, and neither we nor they have any
control.

This series teaches upload-pack to periodically send an empty sideband
data packet when pack-objects is being quiet. That keeps a small amount
of data flowing, and should be backwards compatible. I hand-tested it
against JGit, dulwich (via the mercurial git plugin), libgit2, and old
versions of git, and all worked fine.  It has also been running on
github.com for about a week and a half, and nobody has reported any
problems.

  [1/2]: upload-pack: send keepalive packets during pack computation
  [2/2]: upload-pack: bump keepalive default to 5 seconds

-Peff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] upload-pack: send keepalive packets during pack computation
  2013-09-08  8:59 [PATCH 0/2] upload-pack keepalive Jeff King
@ 2013-09-08  9:01 ` Jeff King
  2013-09-09  7:45   ` Eric Sunshine
  2013-09-08  9:02 ` [PATCH 2/2] upload-pack: bump keepalive default to 5 seconds Jeff King
  1 sibling, 1 reply; 4+ messages in thread
From: Jeff King @ 2013-09-08  9:01 UTC (permalink / raw)
  To: git

Whenn upload-pack has started pack-objects, there may be a
quiet period while pack-objects prepares the pack (i.e.,
counting objects and delta compression).  Normally we would
see (and send to the client) progress information, but if
"--quiet" is in effect, pack-objects will produce nothing at
all until the pack data is ready. On a large repository,
this can take tens of seconds (or even minutes if the system
is loaded or the repository is badly packed). Clients or
intermediate proxies can sometimes give up in this
situation, assuming that the server or connection has hung.

This patch introduces a "keepalive" option; if upload-pack
sees no data from pack-objects for a certain number of
seconds, it will send an empty sideband data packet to let
the other side know that we are still working on it.

Signed-off-by: Jeff King <peff@peff.net>
---
 Documentation/config.txt | 11 +++++++++++
 upload-pack.c            | 25 ++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index ec57a15..5d748f7 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2216,6 +2216,17 @@ uploadpack.allowtipsha1inwant::
 	of a hidden ref (by default, such a request is rejected).
 	see also `uploadpack.hiderefs`.
 
+uploadpack.keepalive::
+	When `upload-pack` has started `pack-objects`, there may be a
+	quiet period while `pack-objects` prepares the pack. Normally
+	it would output progress information, but if `--quiet` was used
+	for the fetch, `pack-objects` will output nothing at all until
+	the pack data begins. Some clients and networks may consider
+	the server to be hung and give up. Setting this option instructs
+	`upload-pack` to send an empty keepalive packet every
+	`uploadpack.keepalive` seconds. Setting this option to 0
+	disables keepalive packets entirely. The default is 0.
+
 url.<base>.insteadOf::
 	Any URL that starts with this value will be rewritten to
 	start, instead, with <base>. In cases where some site serves a
diff --git a/upload-pack.c b/upload-pack.c
index 127e59a..c3e4a20 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -40,6 +40,7 @@ static unsigned int timeout;
 static struct object_array want_obj;
 static struct object_array extra_edge_obj;
 static unsigned int timeout;
+static int keepalive = -1;
 /* 0 for no sideband,
  * otherwise maximum packet size (up to 65520 bytes).
  */
@@ -200,6 +201,7 @@ static void create_pack_file(void)
 	while (1) {
 		struct pollfd pfd[2];
 		int pe, pu, pollsize;
+		int ret;
 
 		reset_timeout();
 
@@ -222,7 +224,8 @@ static void create_pack_file(void)
 		if (!pollsize)
 			break;
 
-		if (poll(pfd, pollsize, -1) < 0) {
+		ret = poll(pfd, pollsize, 1000 * keepalive);
+		if (ret < 0) {
 			if (errno != EINTR) {
 				error("poll failed, resuming: %s",
 				      strerror(errno));
@@ -284,6 +287,21 @@ static void create_pack_file(void)
 			if (sz < 0)
 				goto fail;
 		}
+
+		/*
+		 * We hit the keepalive timeout without saying anything; send
+		 * an empty message on the data sideband just to let the other
+		 * side know we're still working on it, but don't have any data
+		 * yet.
+		 *
+		 * If we don't have a sideband channel, there's no room in the
+		 * protocol to say anything, so those clients are just out of
+		 * luck.
+		 */
+		if (!ret && use_sideband) {
+			static const char buf[] = "0005\1";
+			write_or_die(1, buf, 5);
+		}
 	}
 
 	if (finish_command(&pack_objects)) {
@@ -785,6 +803,11 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
 {
 	if (!strcmp("uploadpack.allowtipsha1inwant", var))
 		allow_tip_sha1_in_want = git_config_bool(var, value);
+	else if (!strcmp("uploadpack.keepalive", var)) {
+		keepalive = git_config_int(var, value);
+		if (!keepalive)
+			keepalive = -1;
+	}
 	return parse_hide_refs_config(var, value, "uploadpack");
 }
 
-- 
1.8.4.2.g87d4a77

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] upload-pack: bump keepalive default to 5 seconds
  2013-09-08  8:59 [PATCH 0/2] upload-pack keepalive Jeff King
  2013-09-08  9:01 ` [PATCH 1/2] upload-pack: send keepalive packets during pack computation Jeff King
@ 2013-09-08  9:02 ` Jeff King
  1 sibling, 0 replies; 4+ messages in thread
From: Jeff King @ 2013-09-08  9:02 UTC (permalink / raw)
  To: git

From: Jeff King <peff@peff.net>

There is no reason not to turn on keepalives by default.
They take very little bandwidth, and significantly less than
the progress reporting they are replacing. And in the case
that progress reporting is on, we should never need to send
a keepalive anyway, as we will constantly be showing
progress and resetting the keepalive timer.

We do not necessarily know what the client's idea of a
reasonable timeout is, so let's keep this on the low side of
5 seconds. That is high enough that we will always prefer
our normal 1-second progress reports to sending a keepalive
packet, but low enough that no sane client should consider
the connection hung.

Signed-off-by: Jeff King <peff@peff.net>
---
 Documentation/config.txt | 2 +-
 upload-pack.c            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5d748f7..6b35578 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2225,7 +2225,7 @@ uploadpack.keepalive::
 	the server to be hung and give up. Setting this option instructs
 	`upload-pack` to send an empty keepalive packet every
 	`uploadpack.keepalive` seconds. Setting this option to 0
-	disables keepalive packets entirely. The default is 0.
+	disables keepalive packets entirely. The default is 5 seconds.
 
 url.<base>.insteadOf::
 	Any URL that starts with this value will be rewritten to
diff --git a/upload-pack.c b/upload-pack.c
index c3e4a20..04a8707 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -40,7 +40,7 @@ static unsigned int timeout;
 static struct object_array want_obj;
 static struct object_array extra_edge_obj;
 static unsigned int timeout;
-static int keepalive = -1;
+static int keepalive = 5;
 /* 0 for no sideband,
  * otherwise maximum packet size (up to 65520 bytes).
  */
-- 
1.8.4.2.g87d4a77

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] upload-pack: send keepalive packets during pack computation
  2013-09-08  9:01 ` [PATCH 1/2] upload-pack: send keepalive packets during pack computation Jeff King
@ 2013-09-09  7:45   ` Eric Sunshine
  0 siblings, 0 replies; 4+ messages in thread
From: Eric Sunshine @ 2013-09-09  7:45 UTC (permalink / raw)
  To: Jeff King; +Cc: Git List

On Sun, Sep 8, 2013 at 5:01 AM, Jeff King <peff@peff.net> wrote:
> Whenn upload-pack has started pack-objects, there may be a

s/Whenn/When/

> quiet period while pack-objects prepares the pack (i.e.,
> counting objects and delta compression).  Normally we would
> see (and send to the client) progress information, but if
> "--quiet" is in effect, pack-objects will produce nothing at
> all until the pack data is ready. On a large repository,
> this can take tens of seconds (or even minutes if the system
> is loaded or the repository is badly packed). Clients or
> intermediate proxies can sometimes give up in this
> situation, assuming that the server or connection has hung.
>
> This patch introduces a "keepalive" option; if upload-pack
> sees no data from pack-objects for a certain number of
> seconds, it will send an empty sideband data packet to let
> the other side know that we are still working on it.
>
> Signed-off-by: Jeff King <peff@peff.net>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-09-09  7:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-08  8:59 [PATCH 0/2] upload-pack keepalive Jeff King
2013-09-08  9:01 ` [PATCH 1/2] upload-pack: send keepalive packets during pack computation Jeff King
2013-09-09  7:45   ` Eric Sunshine
2013-09-08  9:02 ` [PATCH 2/2] upload-pack: bump keepalive default to 5 seconds Jeff King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).