aboutsummaryrefslogtreecommitdiff
path: root/fs.go
diff options
context:
space:
mode:
authorGravatar Aliaksandr Valialkin <valyala@gmail.com> 2017-05-17 14:35:37 +0300
committerGravatar Aliaksandr Valialkin <valyala@gmail.com> 2017-05-17 14:45:31 +0300
commit30e92af08fad62919ff2eae84f530a2f52a547c3 (patch)
tree5a565c9ac513e70971d495f5a32d1e3ac36bf91f /fs.go
parentclient: properly extract tls ServerName from address without port (diff)
downloadfasthttp-30e92af08fad62919ff2eae84f530a2f52a547c3.tar.gz
fasthttp-30e92af08fad62919ff2eae84f530a2f52a547c3.tar.bz2
fasthttp-30e92af08fad62919ff2eae84f530a2f52a547c3.zip
Limit heap memory usage when compressing high number of concurrent responses
Previously each concurrent compression could allocate huge compression state with the size up to 1Mb each. So 10K concurrent connections could result in 10Gb of compression state in the heap. This CL limits the number of compression states among concurrent requests when {Append,Write}{Gzip,Deflate}* functions are called to O(GOMAXPROCS). These functions are used by CompressHandler* for non-streaming responses, i.e. it should cover the majority of use cases. Memory usage for 10K concurrent connections that compress responses drops from 10Gb to 200Mb after this CL.
Diffstat (limited to 'fs.go')
-rw-r--r--fs.go11
1 files changed, 3 insertions, 8 deletions
diff --git a/fs.go b/fs.go
index c36073d..0d83b60 100644
--- a/fs.go
+++ b/fs.go
@@ -958,12 +958,7 @@ func (h *fsHandler) createDirIndex(base *URI, dirPath string, mustCompress bool)
if mustCompress {
var zbuf ByteBuffer
- zw := acquireGzipWriter(&zbuf, CompressDefaultCompression)
- _, err = zw.Write(w.B)
- releaseGzipWriter(zw)
- if err != nil {
- return nil, fmt.Errorf("error when compressing automatically generated index for directory %q: %s", dirPath, err)
- }
+ zbuf.B = AppendGzipBytesLevel(zbuf.B, w.B, CompressDefaultCompression)
w = &zbuf
}
@@ -1048,12 +1043,12 @@ func (h *fsHandler) compressFileNolock(f *os.File, fileInfo os.FileInfo, filePat
return nil, errNoCreatePermission
}
- zw := acquireGzipWriter(zf, CompressDefaultCompression)
+ zw := acquireStacklessGzipWriter(zf, CompressDefaultCompression)
_, err = copyZeroAlloc(zw, f)
if err1 := zw.Flush(); err == nil {
err = err1
}
- releaseGzipWriter(zw)
+ releaseStacklessGzipWriter(zw, CompressDefaultCompression)
zf.Close()
f.Close()
if err != nil {