summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuru Can Celasun <dcelasun@apache.org>2020-09-30 07:25:51 +0100
committerGitHub <noreply@github.com>2020-09-30 07:25:51 +0100
commit077b5fce825e79d84592fff893639b92b637eec7 (patch)
tree71b623e3085c1d77d53a6189a0658f86a9b5e7ed
parent062521f3b6f578d2b78f0ba189cf5d7968074cb1 (diff)
downloadthrift-077b5fce825e79d84592fff893639b92b637eec7.tar.gz
go: Use sync.Pool for gzip in HTTP transport
b67cad4 introduced transparent gzip support for the HTTP transport but calling gzip.NewWriter() with every request causes a large number of memory allocations [1] and can create GC pressure. Avoid this by using a sync.Pool for gzip writers. [1] https://old.reddit.com/r/golang/comments/9uejp4/usage_of_syncpool_for_gzipwriter_in_http_handlers/e94jh8c/
-rw-r--r--lib/go/thrift/http_transport.go15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/go/thrift/http_transport.go b/lib/go/thrift/http_transport.go
index 66f0f388a..bc6922762 100644
--- a/lib/go/thrift/http_transport.go
+++ b/lib/go/thrift/http_transport.go
@@ -24,6 +24,7 @@ import (
"io"
"net/http"
"strings"
+ "sync"
)
// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function
@@ -40,14 +41,24 @@ func NewThriftHandlerFunc(processor TProcessor,
// gz transparently compresses the HTTP response if the client supports it.
func gz(handler http.HandlerFunc) http.HandlerFunc {
+ sp := &sync.Pool{
+ New: func() interface{} {
+ return gzip.NewWriter(nil)
+ },
+ }
+
return func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
handler(w, r)
return
}
w.Header().Set("Content-Encoding", "gzip")
- gz := gzip.NewWriter(w)
- defer gz.Close()
+ gz := sp.Get().(*gzip.Writer)
+ gz.Reset(w)
+ defer func() {
+ _ = gz.Close()
+ sp.Put(gz)
+ }()
gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
handler(gzw, r)
}