Skip to content

Commit 7b8315b

Browse files
committed
Merge branch 'jk/upload-pack-keepalive'
When running "fetch -q", a long silence while the sender side computes the set of objects to send can be mistaken by proxies as dropped connection. The server side has been taught to send a small empty messages to keep the connection alive. * jk/upload-pack-keepalive: upload-pack: bump keepalive default to 5 seconds upload-pack: send keepalive packets during pack computation
2 parents f406140 + 115dedd commit 7b8315b

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
@@ -2288,6 +2288,17 @@ uploadpack.allowtipsha1inwant::
22882288
of a hidden ref (by default, such a request is rejected).
22892289
see also `uploadpack.hiderefs`.
22902290

2291+
uploadpack.keepalive::
2292+
When `upload-pack` has started `pack-objects`, there may be a
2293+
quiet period while `pack-objects` prepares the pack. Normally
2294+
it would output progress information, but if `--quiet` was used
2295+
for the fetch, `pack-objects` will output nothing at all until
2296+
the pack data begins. Some clients and networks may consider
2297+
the server to be hung and give up. Setting this option instructs
2298+
`upload-pack` to send an empty keepalive packet every
2299+
`uploadpack.keepalive` seconds. Setting this option to 0
2300+
disables keepalive packets entirely. The default is 5 seconds.
2301+
22912302
url.<base>.insteadOf::
22922303
Any URL that starts with this value will be rewritten to
22932304
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
@@ -41,6 +41,7 @@ static struct object_array have_obj;
4141
static struct object_array want_obj;
4242
static struct object_array extra_edge_obj;
4343
static unsigned int timeout;
44+
static int keepalive = 5;
4445
/* 0 for no sideband,
4546
* otherwise maximum packet size (up to 65520 bytes).
4647
*/
@@ -134,6 +135,7 @@ static void create_pack_file(void)
134135
while (1) {
135136
struct pollfd pfd[2];
136137
int pe, pu, pollsize;
138+
int ret;
137139

138140
reset_timeout();
139141

@@ -156,7 +158,8 @@ static void create_pack_file(void)
156158
if (!pollsize)
157159
break;
158160

159-
if (poll(pfd, pollsize, -1) < 0) {
161+
ret = poll(pfd, pollsize, 1000 * keepalive);
162+
if (ret < 0) {
160163
if (errno != EINTR) {
161164
error("poll failed, resuming: %s",
162165
strerror(errno));
@@ -218,6 +221,21 @@ static void create_pack_file(void)
218221
if (sz < 0)
219222
goto fail;
220223
}
224+
225+
/*
226+
* We hit the keepalive timeout without saying anything; send
227+
* an empty message on the data sideband just to let the other
228+
* side know we're still working on it, but don't have any data
229+
* yet.
230+
*
231+
* If we don't have a sideband channel, there's no room in the
232+
* protocol to say anything, so those clients are just out of
233+
* luck.
234+
*/
235+
if (!ret && use_sideband) {
236+
static const char buf[] = "0005\1";
237+
write_or_die(1, buf, 5);
238+
}
221239
}
222240

223241
if (finish_command(&pack_objects)) {
@@ -722,6 +740,11 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
722740
{
723741
if (!strcmp("uploadpack.allowtipsha1inwant", var))
724742
allow_tip_sha1_in_want = git_config_bool(var, value);
743+
else if (!strcmp("uploadpack.keepalive", var)) {
744+
keepalive = git_config_int(var, value);
745+
if (!keepalive)
746+
keepalive = -1;
747+
}
725748
return parse_hide_refs_config(var, value, "uploadpack");
726749
}
727750

0 commit comments

Comments
 (0)