diff --git a/CHANGELOG.md b/CHANGELOG.md index cc2d610e..99bb53eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#538](https://github.com/spegel-org/spegel/pull/538) Replace mock OCI client with in memory client. - [#552](https://github.com/spegel-org/spegel/pull/552) Add support for VerticalPodAutoscaler in the Helm chart. - [#556](https://github.com/spegel-org/spegel/pull/556) Add configuration for revisionHistoryLimit in the Helm Chart. +- [#573](https://github.com/spegel-org/spegel/pull/573) Use buffer pool for proxy copying data. ### Changed diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go new file mode 100644 index 00000000..3f96e166 --- /dev/null +++ b/internal/buffer/buffer.go @@ -0,0 +1,26 @@ +package buffer + +import "sync" + +type BufferPool struct { + pool sync.Pool +} + +func NewBufferPool() *BufferPool { + return &BufferPool{ + pool: sync.Pool{ + New: func() interface{} { + return make([]byte, 32*1024) + }, + }, + } +} + +func (p *BufferPool) Get() []byte { + return p.pool.Get().([]byte) +} + +func (p *BufferPool) Put(b []byte) { + //nolint: staticcheck // false positive + p.pool.Put(b) +} diff --git a/internal/buffer/buffer_test.go b/internal/buffer/buffer_test.go new file mode 100644 index 00000000..76916b52 --- /dev/null +++ b/internal/buffer/buffer_test.go @@ -0,0 +1,16 @@ +package buffer + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBufferPool(t *testing.T) { + t.Parallel() + + bufferPool := NewBufferPool() + b := bufferPool.Get() + require.Len(t, b, 32*1024) + bufferPool.Put(b) +} diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index faea712b..e2c3aa3e 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -16,6 +16,7 @@ import ( "github.com/go-logr/logr" + "github.com/spegel-org/spegel/internal/buffer" "github.com/spegel-org/spegel/internal/mux" "github.com/spegel-org/spegel/pkg/metrics" "github.com/spegel-org/spegel/pkg/oci" @@ -28,6 +29,7 @@ const ( ) type Registry struct { + bufferPool *buffer.BufferPool log logr.Logger throttler *throttle.Throttler ociClient oci.Client @@ -90,6 +92,7 @@ func NewRegistry(ociClient oci.Client, router routing.Router, opts ...Option) *R resolveRetries: 3, resolveTimeout: 20 * time.Millisecond, resolveLatestTag: true, + bufferPool: buffer.NewBufferPool(), } for _, opt := range opts { opt(r) @@ -280,6 +283,7 @@ func (r *Registry) handleMirror(rw mux.ResponseWriter, req *http.Request, ref re Host: ipAddr.String(), } proxy := httputil.NewSingleHostReverseProxy(u) + proxy.BufferPool = r.bufferPool proxy.Transport = r.transport proxy.ErrorHandler = func(_ http.ResponseWriter, _ *http.Request, err error) { log.Error(err, "request to mirror failed", "attempt", mirrorAttempts)