From 71f05bbfb75a085aabcbc979af0919174a943010 Mon Sep 17 00:00:00 2001 From: Bruno Michel Date: Thu, 28 Nov 2024 11:06:12 +0100 Subject: [PATCH] Fix HTTP keep-alive for CouchDB connections Golang can reuse HTTP connections with keep alive, but the response body must have been fully read and closed. In the couchdb package, we were reading the body for sucessful response with a json.Decoder. It only reads a JSON value, and most responses from CouchDB have an additional \n after that JSON value. This last byte was not read from the response body, and it prevents Golang from reusing the connection. So, we are doing a new HTTP connection (with DNS resolution and TLS handshake) for each request to CouchDB. --- pkg/couchdb/couchdb.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/couchdb/couchdb.go b/pkg/couchdb/couchdb.go index c2fb9da5abf..33e0176eb33 100644 --- a/pkg/couchdb/couchdb.go +++ b/pkg/couchdb/couchdb.go @@ -311,7 +311,11 @@ func makeRequest(db prefixer.Prefixer, doctype, method, path string, reqbody int log.Error(err.Error()) return err } - defer resp.Body.Close() + defer func() { + // Flush the body, so that the connection can be reused by keep-alive + _, _ = io.Copy(io.Discard, resp.Body) + _ = resp.Body.Close() + }() if elapsed.Seconds() >= 10 { log.Infof("slow request on %s %s (%s)", method, path, elapsed) @@ -322,8 +326,6 @@ func makeRequest(db prefixer.Prefixer, doctype, method, path string, reqbody int return err } if resbody == nil { - // Flush the body, so that the connection can be reused by keep-alive - _, _ = io.Copy(io.Discard, resp.Body) return nil }