From faeeeab87a1ee734297ef81ee8e1ffa701fff1ae Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Fri, 14 Jul 2023 15:23:28 +0300 Subject: [PATCH] [#114] pool: Don't use part buffers when client cut is off Signed-off-by: Denis Kirillov --- pool/parts_buffer_pool.go | 5 ++--- pool/pool.go | 30 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/pool/parts_buffer_pool.go b/pool/parts_buffer_pool.go index d02de668..828d859f 100644 --- a/pool/parts_buffer_pool.go +++ b/pool/parts_buffer_pool.go @@ -58,9 +58,8 @@ func (p *PartsBufferPool) FreeBuffer(buff *PartBuffer) error { p.mu.Lock() defer p.mu.Unlock() - used := p.limit - p.available - if buff.len > used { - return fmt.Errorf("buffer size %d to free is greater than used: %d", buff.len, used) + if buff.len+p.available > p.limit { + return fmt.Errorf("buffer size %d to free is too large, available: %d, limit: %d", buff.len, p.available, p.limit) } p.available += buff.len diff --git a/pool/pool.go b/pool/pool.go index 8c0530c1..a3f3b45a 100644 --- a/pool/pool.go +++ b/pool/pool.go @@ -2285,24 +2285,26 @@ func (p *Pool) PutObject(ctx context.Context, prm PrmObjectPut) (oid.ID, error) } } - buff, err := p.partsBufferPool.GetBuffer() - if err != nil { - return oid.ID{}, fmt.Errorf("cannot get buffer for put operations: %w", err) - } - - defer func() { - if errFree := p.partsBufferPool.FreeBuffer(buff); errFree != nil { - p.log(zap.WarnLevel, "failed to free part buffer", zap.Error(err)) + if prm.clientCut { + buff, err := p.partsBufferPool.GetBuffer() + if err != nil { + return oid.ID{}, fmt.Errorf("cannot get buffer for put operations: %w", err) } - }() - prm.setPartBuffer(buff.Buffer) + prm.setPartBuffer(buff.Buffer) - var ni netmap.NetworkInfo - ni.SetCurrentEpoch(p.cache.Epoch()) - ni.SetMaxObjectSize(p.partsBufferPool.ParBufferSize()) // we want to use initial max object size in PayloadSizeLimiter + var ni netmap.NetworkInfo + ni.SetCurrentEpoch(p.cache.Epoch()) + ni.SetMaxObjectSize(p.partsBufferPool.ParBufferSize()) // we want to use initial max object size in PayloadSizeLimiter - prm.setNetworkInfo(ni) + prm.setNetworkInfo(ni) + + defer func() { + if errFree := p.partsBufferPool.FreeBuffer(buff); errFree != nil { + p.log(zap.WarnLevel, "failed to free part buffer", zap.Error(err)) + } + }() + } id, err := ctxCall.client.objectPut(ctx, prm) if err != nil {