Skip to content

Commit 05e9515

Browse files
peffgitster
authored andcommitted
upload-pack: send keepalive packets during pack computation
When 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent edca415 commit 05e9515

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

Documentation/config.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,17 @@ uploadpack.allowtipsha1inwant::
21642164
of a hidden ref (by default, such a request is rejected).
21652165
see also `uploadpack.hiderefs`.
21662166

2167+
uploadpack.keepalive::
2168+
When `upload-pack` has started `pack-objects`, there may be a
2169+
quiet period while `pack-objects` prepares the pack. Normally
2170+
it would output progress information, but if `--quiet` was used
2171+
for the fetch, `pack-objects` will output nothing at all until
2172+
the pack data begins. Some clients and networks may consider
2173+
the server to be hung and give up. Setting this option instructs
2174+
`upload-pack` to send an empty keepalive packet every
2175+
`uploadpack.keepalive` seconds. Setting this option to 0
2176+
disables keepalive packets entirely. The default is 0.
2177+
21672178
url.<base>.insteadOf::
21682179
Any URL that starts with this value will be rewritten to
21692180
start, instead, with <base>. In cases where some site serves a

upload-pack.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static struct object_array have_obj;
4040
static struct object_array want_obj;
4141
static struct object_array extra_edge_obj;
4242
static unsigned int timeout;
43+
static int keepalive = -1;
4344
/* 0 for no sideband,
4445
* otherwise maximum packet size (up to 65520 bytes).
4546
*/
@@ -200,6 +201,7 @@ static void create_pack_file(void)
200201
while (1) {
201202
struct pollfd pfd[2];
202203
int pe, pu, pollsize;
204+
int ret;
203205

204206
reset_timeout();
205207

@@ -222,7 +224,8 @@ static void create_pack_file(void)
222224
if (!pollsize)
223225
break;
224226

225-
if (poll(pfd, pollsize, -1) < 0) {
227+
ret = poll(pfd, pollsize, 1000 * keepalive);
228+
if (ret < 0) {
226229
if (errno != EINTR) {
227230
error("poll failed, resuming: %s",
228231
strerror(errno));
@@ -284,6 +287,21 @@ static void create_pack_file(void)
284287
if (sz < 0)
285288
goto fail;
286289
}
290+
291+
/*
292+
* We hit the keepalive timeout without saying anything; send
293+
* an empty message on the data sideband just to let the other
294+
* side know we're still working on it, but don't have any data
295+
* yet.
296+
*
297+
* If we don't have a sideband channel, there's no room in the
298+
* protocol to say anything, so those clients are just out of
299+
* luck.
300+
*/
301+
if (!ret && use_sideband) {
302+
static const char buf[] = "0005\1";
303+
write_or_die(1, buf, 5);
304+
}
287305
}
288306

289307
if (finish_command(&pack_objects)) {
@@ -785,6 +803,11 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
785803
{
786804
if (!strcmp("uploadpack.allowtipsha1inwant", var))
787805
allow_tip_sha1_in_want = git_config_bool(var, value);
806+
else if (!strcmp("uploadpack.keepalive", var)) {
807+
keepalive = git_config_int(var, value);
808+
if (!keepalive)
809+
keepalive = -1;
810+
}
788811
return parse_hide_refs_config(var, value, "uploadpack");
789812
}
790813

0 commit comments

Comments
 (0)