diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-04-28 14:13:28 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-04-28 14:13:28 +0200 |
commit | cf74a7c15ef3ed0d0c056a02bd26b9824f710741 (patch) | |
tree | 9622157568b7beca87d39ea13b94bd4276bde224 | |
parent | 1144bffe2e9934e9f8b115e6b4d1fdb36ec6d9c0 (diff) |
Re-use response buffers
-rw-r--r-- | client/go/internal/vespa/document/http.go | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/client/go/internal/vespa/document/http.go b/client/go/internal/vespa/document/http.go index f4e4ec694c8..b742c5a463a 100644 --- a/client/go/internal/vespa/document/http.go +++ b/client/go/internal/vespa/document/http.go @@ -34,6 +34,7 @@ type Client struct { now func() time.Time sendCount int32 gzippers sync.Pool + buffers sync.Pool } // ClientOptions specifices the configuration options of a feed client. @@ -81,6 +82,7 @@ func NewClient(options ClientOptions, httpClients []util.HTTPClient) (*Client, e now: nowFunc, } c.gzippers.New = func() any { return gzip.NewWriter(io.Discard) } + c.buffers.New = func() any { return &bytes.Buffer{} } return c, nil } @@ -165,6 +167,12 @@ func (c *Client) gzipWriter(w io.Writer) *gzip.Writer { return gzipWriter } +func (c *Client) buffer() *bytes.Buffer { + buf := c.buffers.Get().(*bytes.Buffer) + buf.Reset() + return buf +} + func (c *Client) createRequest(method, url string, body []byte) (*http.Request, error) { var r io.Reader useGzip := c.options.Compression == CompressionGzip || (c.options.Compression == CompressionAuto && len(body) > 512) @@ -216,7 +224,7 @@ func (c *Client) Send(document Document) Result { } defer resp.Body.Close() elapsed := c.now().Sub(start) - return resultWithResponse(resp, result, document, elapsed) + return c.resultWithResponse(resp, result, document, elapsed) } func resultWithErr(result Result, err error) Result { @@ -226,7 +234,7 @@ func resultWithErr(result Result, err error) Result { return result } -func resultWithResponse(resp *http.Response, result Result, document Document, elapsed time.Duration) Result { +func (c *Client) resultWithResponse(resp *http.Response, result Result, document Document, elapsed time.Duration) Result { result.HTTPStatus = resp.StatusCode result.Stats.Responses++ result.Stats.ResponsesByCode = map[int]int64{resp.StatusCode: 1} @@ -244,12 +252,14 @@ func resultWithResponse(resp *http.Response, result Result, document Document, e Message string `json:"message"` Trace json.RawMessage `json:"trace"` } - b, err := io.ReadAll(resp.Body) + buf := c.buffer() + defer c.buffers.Put(buf) + written, err := io.Copy(buf, resp.Body) if err != nil { result.Status = StatusVespaFailure result.Err = err } else { - if err := json.Unmarshal(b, &body); err != nil { + if err := json.Unmarshal(buf.Bytes(), &body); err != nil { result.Status = StatusVespaFailure result.Err = fmt.Errorf("failed to decode json response: %w", err) } @@ -257,7 +267,7 @@ func resultWithResponse(resp *http.Response, result Result, document Document, e result.Message = body.Message result.Trace = string(body.Trace) result.Stats.BytesSent = int64(len(document.Body)) - result.Stats.BytesRecv = int64(len(b)) + result.Stats.BytesRecv = int64(written) if !result.Success() { result.Stats.Errors++ } |