Browse Source

Better buffers calibration

DarthSim 6 years ago
parent
commit
250ee7914e
5 changed files with 32 additions and 40 deletions
  1. 24 21
      bufpool.go
  2. 2 2
      download.go
  3. 2 2
      gzippool.go
  4. 0 11
      prometheus.go
  5. 4 4
      server.go

+ 24 - 21
bufpool.go

@@ -2,7 +2,6 @@ package main
 
 import (
 	"bytes"
-	"math"
 	"sort"
 	"sync"
 )
@@ -58,27 +57,29 @@ func (p *bufPool) new() *bytes.Buffer {
 }
 
 func (p *bufPool) calibrateAndClean() {
-	var score float64
-
 	sort.Sort(p.calls)
 
-	pos := 0.95 * float64(p.callInd+1)
+	pos := int(float64(len(p.calls)) * 0.95)
+	score := p.calls[pos]
 
-	if pos < 1.0 {
-		score = float64(p.calls[0])
-	} else if pos >= float64(p.callInd) {
-		score = float64(p.calls[p.callInd-1])
-	} else {
-		lower := float64(p.calls[int(pos)-1])
-		upper := float64(p.calls[int(pos)])
-		score = lower + (pos-math.Floor(pos))*(upper-lower)
+	p.callInd = 0
+	p.throughput = 64
+
+	for {
+		if p.throughput > score {
+			break
+		}
+		p.throughput <<= 1
 	}
 
-	p.throughput = int(score)
-	p.callInd = 0
+	for i, buf := range p.buffers {
+		if buf != nil && buf.Cap() > p.throughput {
+			p.buffers[i] = nil
+		}
+	}
 }
 
-func (p *bufPool) get(size int) *bytes.Buffer {
+func (p *bufPool) Get(size int) *bytes.Buffer {
 	p.mutex.Lock()
 	defer p.mutex.Unlock()
 
@@ -120,15 +121,17 @@ func (p *bufPool) get(size int) *bytes.Buffer {
 	return buf
 }
 
-func (p *bufPool) put(buf *bytes.Buffer) {
+func (p *bufPool) Put(buf *bytes.Buffer) {
 	p.mutex.Lock()
 	defer p.mutex.Unlock()
 
-	p.calls[p.callInd] = buf.Cap()
-	p.callInd++
+	if buf.Len() > 0 {
+		p.calls[p.callInd] = buf.Len()
+		p.callInd++
 
-	if p.callInd == len(p.calls) {
-		p.calibrateAndClean()
+		if p.callInd == len(p.calls) {
+			p.calibrateAndClean()
+		}
 	}
 
 	if p.throughput > 0 && buf.Cap() > p.throughput {
@@ -139,7 +142,7 @@ func (p *bufPool) put(buf *bytes.Buffer) {
 		if b == nil {
 			p.buffers[i] = buf
 
-			if prometheusEnabled {
+			if prometheusEnabled && buf.Cap() > 0 {
 				observeBufferSize(p.name, buf.Cap())
 			}
 

+ 2 - 2
download.go

@@ -131,9 +131,9 @@ func readAndCheckImage(ctx context.Context, res *http.Response) (context.Context
 		contentLength, _ = strconv.Atoi(res.Header.Get("Content-Length"))
 	}
 
-	buf := downloadBufPool.get(contentLength)
+	buf := downloadBufPool.Get(contentLength)
 	cancel := func() {
-		downloadBufPool.put(buf)
+		downloadBufPool.Put(buf)
 	}
 
 	if contentLength > buf.Cap() {

+ 2 - 2
gzippool.go

@@ -39,7 +39,7 @@ func (p *gzipPool) grow() {
 	}
 }
 
-func (p *gzipPool) get(w io.Writer) *gzip.Writer {
+func (p *gzipPool) Get(w io.Writer) *gzip.Writer {
 	p.mutex.Lock()
 	defer p.mutex.Unlock()
 
@@ -55,7 +55,7 @@ func (p *gzipPool) get(w io.Writer) *gzip.Writer {
 	return gz
 }
 
-func (p *gzipPool) put(gz *gzip.Writer) {
+func (p *gzipPool) Put(gz *gzip.Writer) {
 	p.mutex.Lock()
 	defer p.mutex.Unlock()
 

+ 0 - 11
prometheus.go

@@ -16,7 +16,6 @@ var (
 	prometheusRequestDuration    prometheus.Histogram
 	prometheusDownloadDuration   prometheus.Histogram
 	prometheusProcessingDuration prometheus.Histogram
-	prometheusBuffersTotal       *prometheus.CounterVec
 	prometheusBufferSize         *prometheus.HistogramVec
 )
 
@@ -50,11 +49,6 @@ func initPrometheus() {
 		Help: "A histogram of the image processing latency.",
 	})
 
-	prometheusBuffersTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
-		Name: "buffers_total",
-		Help: "A counter of the total number of buffers imgproxy allocated.",
-	}, []string{"type"})
-
 	prometheusBufferSize = prometheus.NewHistogramVec(prometheus.HistogramOpts{
 		Name: "buffer_size_megabytes",
 		Help: "A histogram of the buffer size in megabytes.",
@@ -66,7 +60,6 @@ func initPrometheus() {
 		prometheusRequestDuration,
 		prometheusDownloadDuration,
 		prometheusProcessingDuration,
-		prometheusBuffersTotal,
 		prometheusBufferSize,
 	)
 
@@ -96,10 +89,6 @@ func incrementPrometheusErrorsTotal(t string) {
 	prometheusErrorsTotal.With(prometheus.Labels{"type": t}).Inc()
 }
 
-func incrementBuffersTotal(t string) {
-	prometheusBuffersTotal.With(prometheus.Labels{"type": t}).Inc()
-}
-
 func observeBufferSize(t string, cap int) {
 	size := float64(cap) / 1024.0 / 1024.0
 	prometheusBufferSize.With(prometheus.Labels{"type": t}).Observe(size)

+ 4 - 4
server.go

@@ -124,11 +124,11 @@ func respondWithImage(ctx context.Context, reqID string, r *http.Request, rw htt
 	addVaryHeader(rw)
 
 	if conf.GZipCompression > 0 && strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
-		buf := responseGzipBufPool.get(0)
-		defer responseGzipBufPool.put(buf)
+		buf := responseGzipBufPool.Get(0)
+		defer responseGzipBufPool.Put(buf)
 
-		gz := responseGzipPool.get(buf)
-		defer responseGzipPool.put(gz)
+		gz := responseGzipPool.Get(buf)
+		defer responseGzipPool.Put(gz)
 
 		gz.Write(data)
 		gz.Close()