forked from TrueCloudLab/frostfs-node
[#1561] object: Return OUT_OF_RANGE
status
Replace `ErrRangeOutOfBounds` error from `pkg/core/object` package with `ObjectOutOfRange` from `apistatus` package. That error is returned by storage node's server as NeoFS API statuses. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
ccba07fe19
commit
9f7a22e2aa
11 changed files with 46 additions and 27 deletions
|
@ -1,7 +0,0 @@
|
||||||
package object
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// ErrRangeOutOfBounds is a basic error of violation of the boundaries of the
|
|
||||||
// payload of an object.
|
|
||||||
var ErrRangeOutOfBounds = errors.New("payload range is out of bounds")
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/golang-lru/simplelru"
|
"github.com/hashicorp/golang-lru/simplelru"
|
||||||
"github.com/nspcc-dev/hrw"
|
"github.com/nspcc-dev/hrw"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
|
@ -331,7 +330,7 @@ func (b *blobovniczas) getRange(prm GetRangeSmallPrm) (res GetRangeSmallRes, err
|
||||||
|
|
||||||
res, err = b.getRangeFromLevel(prm, p, !ok)
|
res, err = b.getRangeFromLevel(prm, p, !ok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
outOfBounds := errors.Is(err, object.ErrRangeOutOfBounds)
|
outOfBounds := isErrOutOfRange(err)
|
||||||
if !blobovnicza.IsErrNotFound(err) && !outOfBounds {
|
if !blobovnicza.IsErrNotFound(err) && !outOfBounds {
|
||||||
b.log.Debug("could not get object from level",
|
b.log.Debug("could not get object from level",
|
||||||
zap.String("level", p),
|
zap.String("level", p),
|
||||||
|
@ -498,7 +497,7 @@ func (b *blobovniczas) getRangeFromLevel(prm GetRangeSmallPrm, blzPath string, t
|
||||||
res, err := b.getObjectRange(v.(*blobovnicza.Blobovnicza), prm)
|
res, err := b.getObjectRange(v.(*blobovnicza.Blobovnicza), prm)
|
||||||
switch {
|
switch {
|
||||||
case err == nil,
|
case err == nil,
|
||||||
errors.Is(err, object.ErrRangeOutOfBounds):
|
isErrOutOfRange(err):
|
||||||
return res, err
|
return res, err
|
||||||
default:
|
default:
|
||||||
if !blobovnicza.IsErrNotFound(err) {
|
if !blobovnicza.IsErrNotFound(err) {
|
||||||
|
@ -523,7 +522,7 @@ func (b *blobovniczas) getRangeFromLevel(prm GetRangeSmallPrm, blzPath string, t
|
||||||
res, err := b.getObjectRange(active.blz, prm)
|
res, err := b.getObjectRange(active.blz, prm)
|
||||||
switch {
|
switch {
|
||||||
case err == nil,
|
case err == nil,
|
||||||
errors.Is(err, object.ErrRangeOutOfBounds):
|
isErrOutOfRange(err):
|
||||||
return res, err
|
return res, err
|
||||||
default:
|
default:
|
||||||
if !blobovnicza.IsErrNotFound(err) {
|
if !blobovnicza.IsErrNotFound(err) {
|
||||||
|
@ -630,7 +629,9 @@ func (b *blobovniczas) getObjectRange(blz *blobovnicza.Blobovnicza, prm GetRange
|
||||||
payload := obj.Payload()
|
payload := obj.Payload()
|
||||||
|
|
||||||
if uint64(len(payload)) < to {
|
if uint64(len(payload)) < to {
|
||||||
return GetRangeSmallRes{}, object.ErrRangeOutOfBounds
|
var errOutOfRange apistatus.ObjectOutOfRange
|
||||||
|
|
||||||
|
return GetRangeSmallRes{}, errOutOfRange
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetRangeSmallRes{
|
return GetRangeSmallRes{
|
||||||
|
|
11
pkg/local_object_storage/blobstor/errors.go
Normal file
11
pkg/local_object_storage/blobstor/errors.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package blobstor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isErrOutOfRange(err error) bool {
|
||||||
|
return errors.As(err, new(apistatus.ObjectOutOfRange))
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
|
@ -56,7 +55,9 @@ func (b *BlobStor) GetRangeBig(prm GetRangeBigPrm) (GetRangeBigRes, error) {
|
||||||
ln, off := prm.rng.GetLength(), prm.rng.GetOffset()
|
ln, off := prm.rng.GetLength(), prm.rng.GetOffset()
|
||||||
|
|
||||||
if pLen := uint64(len(payload)); pLen < ln+off {
|
if pLen := uint64(len(payload)); pLen < ln+off {
|
||||||
return GetRangeBigRes{}, object.ErrRangeOutOfBounds
|
var errOutOfRange apistatus.ObjectOutOfRange
|
||||||
|
|
||||||
|
return GetRangeBigRes{}, errOutOfRange
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetRangeBigRes{
|
return GetRangeBigRes{
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -184,7 +185,7 @@ func TestBlobstorFailback(t *testing.T) {
|
||||||
require.Equal(t, objs[i].Payload()[1:11], rngRes.Object().Payload())
|
require.Equal(t, objs[i].Payload()[1:11], rngRes.Object().Payload())
|
||||||
|
|
||||||
_, err = e.GetRange(RngPrm{addr: addr, off: errSmallSize + 10, ln: 1})
|
_, err = e.GetRange(RngPrm{addr: addr, off: errSmallSize + 10, ln: 1})
|
||||||
require.ErrorIs(t, err, object.ErrRangeOutOfBounds)
|
require.ErrorAs(t, err, &apistatus.ObjectOutOfRange{})
|
||||||
}
|
}
|
||||||
|
|
||||||
checkShardState(t, e, id[0], 4, shard.ModeDegraded)
|
checkShardState(t, e, id[0], 4, shard.ModeDegraded)
|
||||||
|
|
|
@ -3,7 +3,6 @@ package engine
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util"
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
|
@ -121,7 +120,7 @@ func (e *StorageEngine) getRange(prm RngPrm) (RngRes, error) {
|
||||||
return false
|
return false
|
||||||
case
|
case
|
||||||
shard.IsErrRemoved(err),
|
shard.IsErrRemoved(err),
|
||||||
errors.Is(err, object.ErrRangeOutOfBounds):
|
shard.IsErrOutOfRange(err):
|
||||||
outError = err
|
outError = err
|
||||||
|
|
||||||
return true // stop, return it back
|
return true // stop, return it back
|
||||||
|
@ -152,8 +151,10 @@ func (e *StorageEngine) getRange(prm RngPrm) (RngRes, error) {
|
||||||
|
|
||||||
e.iterateOverSortedShards(prm.addr, func(_ int, sh hashedShard) (stop bool) {
|
e.iterateOverSortedShards(prm.addr, func(_ int, sh hashedShard) (stop bool) {
|
||||||
res, err := sh.GetRange(shPrm)
|
res, err := sh.GetRange(shPrm)
|
||||||
if errors.Is(err, object.ErrRangeOutOfBounds) {
|
if shard.IsErrOutOfRange(err) {
|
||||||
outError = object.ErrRangeOutOfBounds
|
var errOutOfRange apistatus.ObjectOutOfRange
|
||||||
|
|
||||||
|
outError = errOutOfRange
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
obj = res.Object()
|
obj = res.Object()
|
||||||
|
|
|
@ -17,3 +17,9 @@ func IsErrNotFound(err error) bool {
|
||||||
func IsErrRemoved(err error) bool {
|
func IsErrRemoved(err error) bool {
|
||||||
return errors.As(err, new(apistatus.ObjectAlreadyRemoved))
|
return errors.As(err, new(apistatus.ObjectAlreadyRemoved))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsErrOutOfRange checks if an error returned by Shard GetRange method
|
||||||
|
// corresponds to exceeding the object bounds.
|
||||||
|
func IsErrOutOfRange(err error) bool {
|
||||||
|
return errors.As(err, new(apistatus.ObjectOutOfRange))
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package shard
|
package shard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
|
||||||
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
|
@ -129,7 +127,7 @@ func (s *Shard) fetchObjectData(addr oid.Address, skipMeta bool, big, small stor
|
||||||
|
|
||||||
if skipMeta || err != nil {
|
if skipMeta || err != nil {
|
||||||
res, err = small(s.blobStor, nil)
|
res, err = small(s.blobStor, nil)
|
||||||
if err == nil || errors.Is(err, object.ErrRangeOutOfBounds) {
|
if err == nil || IsErrOutOfRange(err) {
|
||||||
return res, false, err
|
return res, false, err
|
||||||
}
|
}
|
||||||
res, err = big(s.blobStor, nil)
|
res, err = big(s.blobStor, nil)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package getsvc
|
package getsvc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -93,8 +93,11 @@ func (exec *execCtx) initFromChild(obj oid.ID) (prev *oid.ID, children []oid.ID)
|
||||||
parSize := par.PayloadSize()
|
parSize := par.PayloadSize()
|
||||||
|
|
||||||
if seekOff+seekLen > parSize {
|
if seekOff+seekLen > parSize {
|
||||||
|
var errOutOfRange apistatus.ObjectOutOfRange
|
||||||
|
|
||||||
|
exec.err = errOutOfRange
|
||||||
exec.status = statusOutOfRange
|
exec.status = statusOutOfRange
|
||||||
exec.err = object.ErrRangeOutOfBounds
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package getsvc
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -16,6 +15,7 @@ func (exec *execCtx) executeLocal() {
|
||||||
|
|
||||||
var errSplitInfo *objectSDK.SplitInfoError
|
var errSplitInfo *objectSDK.SplitInfoError
|
||||||
var errRemoved apistatus.ObjectAlreadyRemoved
|
var errRemoved apistatus.ObjectAlreadyRemoved
|
||||||
|
var errOutOfRange apistatus.ObjectOutOfRange
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
|
@ -36,8 +36,8 @@ func (exec *execCtx) executeLocal() {
|
||||||
exec.status = statusVIRTUAL
|
exec.status = statusVIRTUAL
|
||||||
mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo())
|
mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo())
|
||||||
exec.err = objectSDK.NewSplitInfoError(exec.infoSplit)
|
exec.err = objectSDK.NewSplitInfoError(exec.infoSplit)
|
||||||
case errors.Is(err, object.ErrRangeOutOfBounds):
|
case errors.As(err, &errOutOfRange):
|
||||||
exec.status = statusOutOfRange
|
exec.status = statusOutOfRange
|
||||||
exec.err = object.ErrRangeOutOfBounds
|
exec.err = errOutOfRange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ func (exec *execCtx) processNode(ctx context.Context, info client.NodeInfo) bool
|
||||||
|
|
||||||
var errSplitInfo *objectSDK.SplitInfoError
|
var errSplitInfo *objectSDK.SplitInfoError
|
||||||
var errRemoved *apistatus.ObjectAlreadyRemoved
|
var errRemoved *apistatus.ObjectAlreadyRemoved
|
||||||
|
var errOutOfRange *apistatus.ObjectOutOfRange
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
|
@ -47,6 +48,9 @@ func (exec *execCtx) processNode(ctx context.Context, info client.NodeInfo) bool
|
||||||
case errors.As(err, &errRemoved):
|
case errors.As(err, &errRemoved):
|
||||||
exec.status = statusINHUMED
|
exec.status = statusINHUMED
|
||||||
exec.err = errRemoved
|
exec.err = errRemoved
|
||||||
|
case errors.As(err, &errOutOfRange):
|
||||||
|
exec.status = statusOutOfRange
|
||||||
|
exec.err = errOutOfRange
|
||||||
case errors.As(err, &errSplitInfo):
|
case errors.As(err, &errSplitInfo):
|
||||||
exec.status = statusVIRTUAL
|
exec.status = statusVIRTUAL
|
||||||
mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo())
|
mergeSplitInfo(exec.splitInfo(), errSplitInfo.SplitInfo())
|
||||||
|
|
Loading…
Reference in a new issue