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:
parent
b8fc6dc9f0
commit
250ee7914e
45
bufpool.go
45
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())
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user