Skip to content

Commit c50163a

Browse files
committed
sn/object: Initial support for erasure coding policies by HASH server
Closes #3656. Refs #3423, #3654, #526. Signed-off-by: Leonard Lyubich <[email protected]>
1 parent e247569 commit c50163a

File tree

1 file changed

+49
-2
lines changed

1 file changed

+49
-2
lines changed

pkg/services/object/get/get.go

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77

8+
iec "github.com/nspcc-dev/neofs-node/internal/ec"
89
"github.com/nspcc-dev/neofs-node/pkg/network"
910
"github.com/nspcc-dev/neofs-node/pkg/services/object/internal"
1011
"github.com/nspcc-dev/neofs-node/pkg/util"
@@ -106,14 +107,27 @@ func (s *Service) GetRange(ctx context.Context, prm RangePrm) error {
106107
return s.copyLocalECPartRange(prm.objWriter, prm.addr.Container(), prm.addr.Object(), pi, prm.rng.GetOffset(), prm.rng.GetLength())
107108
}
108109

110+
return s.getRange(ctx, prm, nodeLists, repRules, ecRules, nil)
111+
}
112+
113+
func (s *Service) getRange(ctx context.Context, prm RangePrm, nodeLists [][]netmap.NodeInfo, repRules []uint, ecRules []iec.Rule,
114+
hashPrm *RangeHashPrm) error {
109115
if len(repRules) > 0 { // REP format does not require encoding
110-
err := s.get(ctx, prm.commonPrm, withPreSortedContainerNodes(nodeLists[:len(repRules)], repRules), withPayloadRange(prm.rng)).err
116+
err := s.get(ctx, prm.commonPrm, withPreSortedContainerNodes(nodeLists[:len(repRules)], repRules), withPayloadRange(prm.rng), withHash(hashPrm)).err
111117
if len(ecRules) == 0 || !errors.Is(err, apistatus.ErrObjectNotFound) {
112118
return err
113119
}
114120
}
115121

116122
ecNodeLists := nodeLists[len(repRules):]
123+
if hashPrm != nil && prm.rangeForwarder != nil && !localNodeInSets(s.neoFSNet, nodeLists) {
124+
hashes, err := s.proxyHashRequest(ctx, ecNodeLists, prm.rangeForwarder)
125+
if err == nil {
126+
hashPrm.forwardedRangeHashResponse = hashes
127+
}
128+
return err
129+
}
130+
117131
if prm.forwarder != nil && !localNodeInSets(s.neoFSNet, ecNodeLists) {
118132
return s.proxyGetRequest(ctx, ecNodeLists, prm.forwarder, "RANGE", nil)
119133
}
@@ -123,6 +137,11 @@ func (s *Service) GetRange(ctx context.Context, prm RangePrm) error {
123137
}
124138

125139
func (s *Service) GetRangeHash(ctx context.Context, prm RangeHashPrm) (*RangeHashRes, error) {
140+
nodeLists, repRules, ecRules, err := s.neoFSNet.GetNodesForObject(prm.addr)
141+
if err != nil {
142+
return nil, fmt.Errorf("get nodes for object: %w", err)
143+
}
144+
126145
hashes := make([][]byte, 0, len(prm.rngs))
127146

128147
for _, rng := range prm.rngs {
@@ -142,7 +161,7 @@ func (s *Service) GetRangeHash(ctx context.Context, prm RangeHashPrm) (*RangeHas
142161
hash: util.NewSaltingWriter(h, prm.salt),
143162
})
144163

145-
if err := s.get(ctx, rngPrm.commonPrm, withHash(&prm), withPayloadRange(rngPrm.rng)).err; err != nil {
164+
if err := s.getRange(ctx, rngPrm, nodeLists, repRules, ecRules, &prm); err != nil {
146165
return nil, err
147166
}
148167

@@ -161,6 +180,34 @@ func (s *Service) GetRangeHash(ctx context.Context, prm RangeHashPrm) (*RangeHas
161180
}, nil
162181
}
163182

183+
func (s *Service) proxyHashRequest(ctx context.Context, sortedNodeLists [][]netmap.NodeInfo, proxyFn RangeRequestForwarder) ([][]byte, error) {
184+
for i := range sortedNodeLists {
185+
for j := range sortedNodeLists[i] {
186+
conn, node, err := s.conns.(*clientCacheWrapper)._connect(sortedNodeLists[i][j])
187+
if err != nil {
188+
// TODO: implement address list stringer for lazy encoding
189+
s.log.Debug("get conn to remote node",
190+
zap.String("addresses", network.StringifyGroup(node.AddressGroup())), zap.Error(err))
191+
continue
192+
}
193+
194+
hashes, err := proxyFn(ctx, node, conn)
195+
if err == nil {
196+
return hashes, nil
197+
}
198+
199+
if errors.Is(err, apistatus.ErrObjectAlreadyRemoved) || errors.Is(err, apistatus.ErrObjectAccessDenied) ||
200+
errors.Is(err, apistatus.ErrObjectOutOfRange) || errors.Is(err, ctx.Err()) {
201+
return nil, err
202+
}
203+
204+
s.log.Info("request proxy failed", zap.String("request", "HASH"), zap.Error(err))
205+
}
206+
}
207+
208+
return nil, apistatus.ErrObjectNotFound
209+
}
210+
164211
// Head reads object header from container.
165212
//
166213
// Returns ErrNotFound if the header was not received for the call.

0 commit comments

Comments
 (0)