소스 검색

Delayed download buffer grow

DarthSim 2 년 전
부모
커밋
ad5bd69f80
3개의 변경된 파일22개의 추가작업 그리고 7개의 파일을 삭제
  1. 2 0
      CHANGELOG.md
  2. 6 3
      bufpool/bufpool.go
  3. 14 4
      imagedata/read.go

+ 2 - 0
CHANGELOG.md

@@ -1,6 +1,8 @@
 # Changelog
 
 ## [Unreleased]
+### Fix
+- Fix memory bloat in some cases.
 
 ## [3.7.0] - 2022-07-27
 ### Add

+ 6 - 3
bufpool/bufpool.go

@@ -73,7 +73,7 @@ func (p *Pool) calibrateAndClean() {
 	metrics.SetBufferMaxSize(p.name, p.maxSize)
 }
 
-func (p *Pool) Get(size int) *bytes.Buffer {
+func (p *Pool) Get(size int, grow bool) *bytes.Buffer {
 	p.mutex.Lock()
 	defer p.mutex.Unlock()
 
@@ -115,7 +115,10 @@ func (p *Pool) Get(size int) *bytes.Buffer {
 
 	buf.Reset()
 
-	growSize := imath.Max(size, p.defaultSize)
+	growSize := p.defaultSize
+	if grow {
+		growSize = imath.Max(size, growSize)
+	}
 
 	if growSize > buf.Cap() {
 		buf.Grow(growSize)
@@ -145,7 +148,7 @@ func (p *Pool) Put(buf *bytes.Buffer) {
 		if b == nil {
 			p.buffers[i] = buf
 
-			if buf.Cap() > 0 {
+			if buf.Len() > 0 {
 				metrics.ObserveBufferSize(p.name, buf.Cap())
 			}
 

+ 14 - 4
imagedata/read.go

@@ -44,7 +44,7 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
 		return nil, ErrSourceFileTooBig
 	}
 
-	buf := downloadBufPool.Get(contentLength)
+	buf := downloadBufPool.Get(contentLength, false)
 	cancel := func() { downloadBufPool.Put(buf) }
 
 	if config.MaxSrcFileSize > 0 {
@@ -54,17 +54,27 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
 	br := bufreader.New(r, buf)
 
 	meta, err := imagemeta.DecodeMeta(br)
-	if err == imagemeta.ErrFormat {
-		return nil, ErrSourceImageTypeNotSupported
-	}
 	if err != nil {
+		buf.Reset()
+		cancel()
+
+		if err == imagemeta.ErrFormat {
+			return nil, ErrSourceImageTypeNotSupported
+		}
+
 		return nil, checkTimeoutErr(err)
 	}
 
 	if err = security.CheckDimensions(meta.Width(), meta.Height()); err != nil {
+		buf.Reset()
+		cancel()
 		return nil, err
 	}
 
+	if contentLength > buf.Cap() {
+		buf.Grow(contentLength - buf.Len())
+	}
+
 	if err = br.Flush(); err != nil {
 		cancel()
 		return nil, checkTimeoutErr(err)