From 57efa0bc8eebbc7b26ef9d0c14b4dbbdb7b59de7 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 16 Jan 2025 16:04:40 +0300 Subject: [PATCH] [#1604] policer: Properly handle maintenance nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consider `REP 1 REP 1` placement (selects/filters are omitted). The placement is `[1, 2], [1, 0]`. We are the 0-th node. Node 1 is under maintenance, so we do not replicate object on the node 2. In the second replication group node 1 is under maintenance, but current caching logic considers it as "replica holder" and removes local copy. VoilĂ , we have DL if the object is missing from the node 1. Signed-off-by: Evgenii Stratonikov --- pkg/services/policer/check.go | 6 +++++- pkg/services/policer/nodecache.go | 1 + pkg/services/policer/policer_test.go | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/services/policer/check.go b/pkg/services/policer/check.go index f79ffbece..7ac5fc9e0 100644 --- a/pkg/services/policer/check.go +++ b/pkg/services/policer/check.go @@ -128,6 +128,10 @@ func (p *Policer) processRepNodes(ctx context.Context, requirements *placementRe if status == nodeHoldsObject { shortage-- } + if status == nodeIsUnderMaintenance { + shortage-- + uncheckedCopies++ + } nodes = append(nodes[:i], nodes[i+1:]...) i-- @@ -174,7 +178,7 @@ func (p *Policer) processRepNodes(ctx context.Context, requirements *placementRe // However, additional copies should not be removed in this case, // because we can remove the only copy this way. func (p *Policer) handleMaintenance(ctx context.Context, node netmap.NodeInfo, checkedNodes nodeCache, shortage uint32, uncheckedCopies int) (uint32, int) { - checkedNodes.set(node, nodeHoldsObject) + checkedNodes.set(node, nodeIsUnderMaintenance) shortage-- uncheckedCopies++ diff --git a/pkg/services/policer/nodecache.go b/pkg/services/policer/nodecache.go index 84a333278..53b64d3fa 100644 --- a/pkg/services/policer/nodecache.go +++ b/pkg/services/policer/nodecache.go @@ -9,6 +9,7 @@ const ( nodeDoesNotHoldObject nodeHoldsObject nodeStatusUnknown + nodeIsUnderMaintenance ) func (st nodeProcessStatus) Processed() bool { diff --git a/pkg/services/policer/policer_test.go b/pkg/services/policer/policer_test.go index ca6bff944..9b9ab99ac 100644 --- a/pkg/services/policer/policer_test.go +++ b/pkg/services/policer/policer_test.go @@ -170,6 +170,14 @@ func TestProcessObject(t *testing.T) { placement: [][]int{{0, 1, 2}}, wantReplicateTo: []int{1, 2}, }, + { + desc: "do not remove local copy when MAINTENANCE status is cached", + objType: objectSDK.TypeRegular, + nodeCount: 3, + policy: `REP 1 REP 1`, + placement: [][]int{{1, 2}, {1, 0}}, + headResult: map[int]error{1: new(apistatus.NodeUnderMaintenance)}, + }, } for i := range tests {