package patchsvc import ( "context" "crypto/ecdsa" "io" getsvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object/get" objectUtil "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object/util" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" patcherSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/patcher" ) func (p *pipeChunkWriter) WriteChunk(_ context.Context, chunk []byte) error { _, err := p.wr.Write(chunk) return err } type rangeProvider struct { getSvc *getsvc.Service addr oid.Address commonPrm *objectUtil.CommonPrm localNodeKey *ecdsa.PrivateKey } var _ patcherSDK.RangeProvider = (*rangeProvider)(nil) func (r *rangeProvider) GetRange(ctx context.Context, rng *objectSDK.Range) io.Reader { // Remote GetRange request to a container node uses an SDK-client that fails range validation // with zero-length. However, from the patcher's point of view, such request is still valid. if rng.GetLength() == 0 { return &nopReader{} } pipeReader, pipeWriter := io.Pipe() var rngPrm getsvc.RangePrm rngPrm.SetSignerKey(r.localNodeKey) rngPrm.SetCommonParameters(r.commonPrm) rngPrm.WithAddress(r.addr) rngPrm.SetChunkWriter(&pipeChunkWriter{ wr: pipeWriter, }) rngPrm.SetRange(rng) getRangeErr := make(chan error) go func() { defer pipeWriter.Close() select { case <-ctx.Done(): pipeWriter.CloseWithError(ctx.Err()) case err := <-getRangeErr: pipeWriter.CloseWithError(err) } }() go func() { getRangeErr <- r.getSvc.GetRange(ctx, rngPrm) }() return pipeReader } type nopReader struct{} func (nopReader) Read(_ []byte) (int, error) { return 0, io.EOF }