summaryrefslogtreecommitdiff
path: root/remote-curl.c
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2014-02-18 05:34:20 -0500
committerLibravatar Junio C Hamano <gitster@pobox.com>2014-02-18 15:50:57 -0800
commitbeed336c3e35acfd7aad9033eb9294e42b9530af (patch)
tree3837ffddfd800be487ea85cc2a0909b110fd0b0b /remote-curl.c
parentGit 1.9.0 (diff)
downloadtgif-beed336c3e35acfd7aad9033eb9294e42b9530af.tar.xz
http: never use curl_easy_perform
We currently don't reuse http connections when fetching via the smart-http protocol. This is bad because the TCP handshake introduces latency, and especially because SSL connection setup may be non-trivial. We can fix it by consistently using curl's "multi" interface. The reason is rather complicated: Our http code has two ways of being used: queuing many "slots" to be fetched in parallel, or fetching a single request in a blocking manner. The parallel code is built on curl's "multi" interface. Most of the single-request code uses http_request, which is built on top of the parallel code (we just feed it one slot, and wait until it finishes). However, one could also accomplish the single-request scheme by avoiding curl's multi interface entirely and just using curl_easy_perform. This is simpler, and is used by post_rpc in the smart-http protocol. It does work to use the same curl handle in both contexts, as long as it is not at the same time. However, internally curl may not share all of the cached resources between both contexts. In particular, a connection formed using the "multi" code will go into a reuse pool connected to the "multi" object. Further requests using the "easy" interface will not be able to reuse that connection. The smart http protocol does ref discovery via http_request, which uses the "multi" interface, and then follows up with the "easy" interface for its rpc calls. As a result, we make two HTTP connections rather than reusing a single one. We could teach the ref discovery to use the "easy" interface. But it is only once we have done this discovery that we know whether the protocol will be smart or dumb. If it is dumb, then our further requests, which want to fetch objects in parallel, will not be able to reuse the same connection. Instead, this patch switches post_rpc to build on the parallel interface, which means that we use it consistently everywhere. It's a little more complicated to use, but since we have the infrastructure already, it doesn't add any code; we can just factor out the relevant bits from http_request. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'remote-curl.c')
-rw-r--r--remote-curl.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/remote-curl.c b/remote-curl.c
index 10cb0114ea..52c2d96ce6 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -423,11 +423,8 @@ static int run_slot(struct active_request_slot *slot,
if (!results)
results = &results_buf;
- slot->results = results;
- slot->curl_result = curl_easy_perform(slot->curl);
- finish_active_slot(slot);
+ err = run_one_slot(slot, results);
- err = handle_curl_result(results);
if (err != HTTP_OK && err != HTTP_REAUTH) {
error("RPC failed; result=%d, HTTP code = %ld",
results->curl_result, results->http_code);