2024-08-12 14:11:10 +00:00
|
|
|
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 {
|
2024-08-27 13:09:59 +00:00
|
|
|
// 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{}
|
|
|
|
}
|
|
|
|
|
2024-08-12 14:11:10 +00:00
|
|
|
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
|
|
|
|
}
|
2024-08-27 13:09:59 +00:00
|
|
|
|
|
|
|
type nopReader struct{}
|
|
|
|
|
|
|
|
func (nopReader) Read(_ []byte) (int, error) {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|