Commit 4139f377 authored by Nick Thomas's avatar Nick Thomas

Merge branch 'jv-workhorse-gzip-pool' into 'master'

Workhorse: re-use *gzip.Writer instances

See merge request gitlab-org/gitlab!84175
parents 24a5b0a0 a327f680
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"sync"
"github.com/golang/gddo/httputil" "github.com/golang/gddo/httputil"
grpccodes "google.golang.org/grpc/codes" grpccodes "google.golang.org/grpc/codes"
...@@ -64,21 +65,43 @@ func handleGetInfoRefsWithGitaly(ctx context.Context, responseWriter *HttpRespon ...@@ -64,21 +65,43 @@ func handleGetInfoRefsWithGitaly(ctx context.Context, responseWriter *HttpRespon
return err return err
} }
var w io.Writer var w io.WriteCloser = nopCloser{responseWriter}
if encoding == "gzip" { if encoding == "gzip" {
gzWriter := gzip.NewWriter(responseWriter) gzWriter := getGzWriter(responseWriter)
w = gzWriter defer putGzWriter(gzWriter)
defer gzWriter.Close()
w = gzWriter
responseWriter.Header().Set("Content-Encoding", "gzip") responseWriter.Header().Set("Content-Encoding", "gzip")
} else {
w = responseWriter
} }
if _, err = io.Copy(w, infoRefsResponseReader); err != nil { if _, err = io.Copy(w, infoRefsResponseReader); err != nil {
return err return err
} }
if err := w.Close(); err != nil {
return err
}
return nil return nil
} }
var gzipPool = &sync.Pool{New: func() interface{} {
// Invariant: the inner writer is io.Discard. We do not want to retain
// response writers of past requests in the pool.
return gzip.NewWriter(io.Discard)
}}
func getGzWriter(w io.Writer) *gzip.Writer {
gzWriter := gzipPool.Get().(*gzip.Writer)
gzWriter.Reset(w)
return gzWriter
}
func putGzWriter(w *gzip.Writer) {
w.Reset(io.Discard) // Maintain pool invariant
gzipPool.Put(w)
}
type nopCloser struct{ io.Writer }
func (nc nopCloser) Close() error { return nil }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment