From 050ad2762c72aceee5e3686fc93fd2be576127d4 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 10 Oct 2022 17:53:26 +0400 Subject: [PATCH] [#1680] replicator: Consider `NODE_UNDER_MAINTENANCE` as OK Node response with `NODE_UNDER_MAINTENANCE` status signals that the node was switched to maintenance mode. There is a delay between the actual switch and the reflection in the network map of up to one epoch. To speed up the reaction to the maintenance, it is required to recognize such node responses in the Policer. Make `Policer.processNodes` to exclude elements with shortage decreasing on `NODE_UNDER_MAINTENANCE` status response. Signed-off-by: Leonard Lyubich --- pkg/services/policer/check.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/pkg/services/policer/check.go b/pkg/services/policer/check.go index 2bd31e272..a06f8f0d9 100644 --- a/pkg/services/policer/check.go +++ b/pkg/services/policer/check.go @@ -3,12 +3,14 @@ package policer import ( "context" "encoding/hex" + "errors" "github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine" headsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/head" "github.com/nspcc-dev/neofs-node/pkg/services/replicator" "github.com/nspcc-dev/neofs-sdk-go/client" + apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" "github.com/nspcc-dev/neofs-sdk-go/netmap" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" "go.uber.org/zap" @@ -191,7 +193,9 @@ func (p *Policer) processNodes(ctx *processPlacementContext, addr oid.Address, continue } - if err != nil { + if isClientErrMaintenance(err) { + handleMaintenance(nodes[i]) + } else if err != nil { p.log.Error("receive object header to check policy compliance", zap.Stringer("object", addr), zap.String("error", err.Error()), @@ -220,3 +224,28 @@ func (p *Policer) processNodes(ctx *processPlacementContext, addr oid.Address, p.replicator.HandleTask(ctx, task, checkedNodes) } } + +// isClientErrMaintenance checks if err corresponds to NeoFS status return +// which tells that node is currently under maintenance. Supports wrapped +// errors. +// +// Similar to client.IsErr___ errors, consider replacing to NeoFS SDK. +func isClientErrMaintenance(err error) bool { + switch unwrapErr(err).(type) { + default: + return false + case + apistatus.NodeUnderMaintenance, + *apistatus.NodeUnderMaintenance: + return true + } +} + +// unwrapErr unwraps error using errors.Unwrap. +func unwrapErr(err error) error { + for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(err) { + err = e + } + + return err +}