[#199] putsvc: Refactor put object

Resolve containedctx linter for streamer and remote target

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-04-03 14:23:53 +03:00 committed by Gitea
parent cecea8053a
commit 27bdddc48f
24 changed files with 171 additions and 125 deletions

View file

@ -1,6 +1,7 @@
package transformer
import (
"context"
"crypto/ecdsa"
"fmt"
@ -53,15 +54,15 @@ func (f *formatter) WriteHeader(obj *object.Object) error {
return nil
}
func (f *formatter) Write(p []byte) (n int, err error) {
n, err = f.prm.NextTarget.Write(p)
func (f *formatter) Write(ctx context.Context, p []byte) (n int, err error) {
n, err = f.prm.NextTarget.Write(ctx, p)
f.sz += uint64(n)
return
}
func (f *formatter) Close() (*AccessIdentifiers, error) {
func (f *formatter) Close(ctx context.Context) (*AccessIdentifiers, error) {
curEpoch := f.prm.NetworkState.CurrentEpoch()
ver := version.Current()
@ -100,7 +101,7 @@ func (f *formatter) Close() (*AccessIdentifiers, error) {
return nil, fmt.Errorf("could not write header to next target: %w", err)
}
if _, err := f.prm.NextTarget.Close(); err != nil {
if _, err := f.prm.NextTarget.Close(ctx); err != nil {
return nil, fmt.Errorf("could not close next target: %w", err)
}

View file

@ -1,10 +1,10 @@
package transformer
import (
"context"
"crypto/sha256"
"fmt"
"hash"
"io"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
@ -27,7 +27,7 @@ type payloadSizeLimiter struct {
previous []oid.ID
chunkWriter io.Writer
chunkWriter writer
splitID *object.SplitID
@ -64,16 +64,16 @@ func (s *payloadSizeLimiter) WriteHeader(hdr *object.Object) error {
return nil
}
func (s *payloadSizeLimiter) Write(p []byte) (int, error) {
if err := s.writeChunk(p); err != nil {
func (s *payloadSizeLimiter) Write(ctx context.Context, p []byte) (int, error) {
if err := s.writeChunk(ctx, p); err != nil {
return 0, err
}
return len(p), nil
}
func (s *payloadSizeLimiter) Close() (*AccessIdentifiers, error) {
return s.release(true)
func (s *payloadSizeLimiter) Close(ctx context.Context) (*AccessIdentifiers, error) {
return s.release(ctx, true)
}
func (s *payloadSizeLimiter) initialize() {
@ -117,19 +117,19 @@ func (s *payloadSizeLimiter) initializeCurrent() {
s.currentHashers = payloadHashersForObject(s.current, s.withoutHomomorphicHash)
// compose multi-writer from target and all payload hashers
ws := make([]io.Writer, 0, 1+len(s.currentHashers)+len(s.parentHashers))
ws := make([]writer, 0, 1+len(s.currentHashers)+len(s.parentHashers))
ws = append(ws, s.target)
for i := range s.currentHashers {
ws = append(ws, s.currentHashers[i].hasher)
ws = append(ws, newWriter(s.currentHashers[i].hasher))
}
for i := range s.parentHashers {
ws = append(ws, s.parentHashers[i].hasher)
ws = append(ws, newWriter(s.parentHashers[i].hasher))
}
s.chunkWriter = io.MultiWriter(ws...)
s.chunkWriter = newMultiWriter(ws...)
}
func payloadHashersForObject(obj *object.Object, withoutHomomorphicHash bool) []*payloadChecksumHasher {
@ -174,7 +174,7 @@ func payloadHashersForObject(obj *object.Object, withoutHomomorphicHash bool) []
return hashers
}
func (s *payloadSizeLimiter) release(finalize bool) (*AccessIdentifiers, error) {
func (s *payloadSizeLimiter) release(ctx context.Context, finalize bool) (*AccessIdentifiers, error) {
// Arg finalize is true only when called from Close method.
// We finalize parent and generate linking objects only if it is more
// than 1 object in split-chain.
@ -194,7 +194,7 @@ func (s *payloadSizeLimiter) release(finalize bool) (*AccessIdentifiers, error)
return nil, fmt.Errorf("could not write header: %w", err)
}
ids, err := s.target.Close()
ids, err := s.target.Close(ctx)
if err != nil {
return nil, fmt.Errorf("could not close target: %w", err)
}
@ -207,7 +207,7 @@ func (s *payloadSizeLimiter) release(finalize bool) (*AccessIdentifiers, error)
s.initializeLinking(ids.Parent())
s.initializeCurrent()
if _, err := s.release(false); err != nil {
if _, err := s.release(ctx, false); err != nil {
return nil, fmt.Errorf("could not release linking object: %w", err)
}
}
@ -228,7 +228,7 @@ func (s *payloadSizeLimiter) initializeLinking(parHdr *object.Object) {
s.current.SetSplitID(s.splitID)
}
func (s *payloadSizeLimiter) writeChunk(chunk []byte) error {
func (s *payloadSizeLimiter) writeChunk(ctx context.Context, chunk []byte) error {
// statement is true if the previous write of bytes reached exactly the boundary.
if s.written > 0 && s.written%s.maxSize == 0 {
if s.written == s.maxSize {
@ -236,7 +236,7 @@ func (s *payloadSizeLimiter) writeChunk(chunk []byte) error {
}
// we need to release current object
if _, err := s.release(false); err != nil {
if _, err := s.release(ctx, false); err != nil {
return fmt.Errorf("could not release object: %w", err)
}
@ -255,7 +255,7 @@ func (s *payloadSizeLimiter) writeChunk(chunk []byte) error {
cut = leftToEdge
}
if _, err := s.chunkWriter.Write(chunk[:cut]); err != nil {
if _, err := s.chunkWriter.Write(ctx, chunk[:cut]); err != nil {
return fmt.Errorf("could not write chunk to target: %w", err)
}
@ -264,7 +264,7 @@ func (s *payloadSizeLimiter) writeChunk(chunk []byte) error {
// if there are more bytes in buffer we call method again to start filling another object
if ln > leftToEdge {
return s.writeChunk(chunk[cut:])
return s.writeChunk(ctx, chunk[cut:])
}
return nil

View file

@ -1,7 +1,7 @@
package transformer
import (
"io"
"context"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
@ -35,7 +35,7 @@ type ObjectTarget interface {
// Can be called multiple times.
//
// Must not be called after Close call.
io.Writer
Write(ctx context.Context, p []byte) (n int, err error)
// Close is used to finish object writing.
//
@ -45,7 +45,7 @@ type ObjectTarget interface {
// Must be called no more than once. Control remains with the caller.
// Re-calling can lead to undefined behavior
// that depends on the implementation.
Close() (*AccessIdentifiers, error)
Close(ctx context.Context) (*AccessIdentifiers, error)
}
// TargetInitializer represents ObjectTarget constructor.

View file

@ -0,0 +1,52 @@
package transformer
import (
"context"
"io"
)
type writer interface {
Write(ctx context.Context, p []byte) (n int, err error)
}
type multiWriter struct {
writers []writer
}
func (t *multiWriter) Write(ctx context.Context, p []byte) (n int, err error) {
for _, w := range t.writers {
n, err = w.Write(ctx, p)
if err != nil {
return
}
if n != len(p) {
err = io.ErrShortWrite
return
}
}
return len(p), nil
}
func newMultiWriter(writers ...writer) writer {
allWriters := make([]writer, 0, len(writers))
for _, w := range writers {
if mw, ok := w.(*multiWriter); ok {
allWriters = append(allWriters, mw.writers...)
} else {
allWriters = append(allWriters, w)
}
}
return &multiWriter{allWriters}
}
type writerWrapper struct {
Writer io.Writer
}
func (w *writerWrapper) Write(_ context.Context, p []byte) (n int, err error) {
return w.Writer.Write(p)
}
func newWriter(w io.Writer) writer {
return &writerWrapper{Writer: w}
}