1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-02-02 11:34:20 +02:00

Better buffers calibration

This commit is contained in:
DarthSim 2019-01-30 16:31:00 +06:00
parent b8fc6dc9f0
commit 250ee7914e
5 changed files with 32 additions and 40 deletions

View File

@ -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())
}

View File

@ -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() {

View File

@ -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()

View File

@ -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)

View File

@ -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()