From 82c2118736a11fd1294488a7c4cc7d0aa5b56b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ege=20G=C3=BCne=C5=9F?= Date: Wed, 30 Oct 2024 20:51:49 +0300 Subject: [PATCH] fix max voter check --- pkg/psmdb/mongo/mongo.go | 59 +++--- pkg/psmdb/mongo/mongo_test.go | 384 ++++++++++++++++++++++++---------- 2 files changed, 309 insertions(+), 134 deletions(-) diff --git a/pkg/psmdb/mongo/mongo.go b/pkg/psmdb/mongo/mongo.go index ce5cce01ab..dd6d532c1b 100644 --- a/pkg/psmdb/mongo/mongo.go +++ b/pkg/psmdb/mongo/mongo.go @@ -917,35 +917,42 @@ func (m *ConfigMembers) SetVotes(compareWith ConfigMembers, unsafePSA bool) { continue } - if votes < MaxVotingMembers { - []ConfigMember(*m)[i].Votes = 1 - votes++ - - if !member.ArbiterOnly { - lastVoteIdx = i - // In unsafe PSA (Primary with a Secondary and an Arbiter), - // we are unable to set the votes and the priority simultaneously. - // Therefore, setting only the votes. - if !unsafePSA || member.Votes == 1 { - priority := DefaultPriority - if c, ok := cm[member.Host]; ok { - priority = c - } - - // Priority can be any number in range [0,1000]. - // We're setting it to 2 as default, to allow - // users to configure external nodes with lower - // priority than local nodes. - []ConfigMember(*m)[i].Priority = priority - } - } - } else if member.ArbiterOnly { + if member.ArbiterOnly { // Arbiter should always have a vote []ConfigMember(*m)[i].Votes = 1 + // Arbiter should never have priority + []ConfigMember(*m)[i].Priority = 0 + } else { + []ConfigMember(*m)[i].Votes = 1 + lastVoteIdx = i + + // In unsafe PSA (Primary with a Secondary and an Arbiter), + // we are unable to set the votes and the priority simultaneously. + // Therefore, setting only the votes. + if !unsafePSA || member.Votes == 1 { + // Priority can be any number in range [0,1000]. + // We're setting it to 2 as default, to allow + // users to configure external nodes with lower + // priority than local nodes. + priority := DefaultPriority + + if c, ok := cm[member.Host]; ok { + priority = c + } - // We're over the max voters limit. Make room for the arbiter - []ConfigMember(*m)[lastVoteIdx].Votes = 0 - []ConfigMember(*m)[lastVoteIdx].Priority = 0 + []ConfigMember(*m)[i].Priority = priority + } + } + votes++ + + if votes > MaxVotingMembers { + if member.ArbiterOnly { + []ConfigMember(*m)[lastVoteIdx].Votes = 0 + []ConfigMember(*m)[lastVoteIdx].Priority = 0 + } else { + []ConfigMember(*m)[i].Votes = 0 + []ConfigMember(*m)[i].Priority = 0 + } } } diff --git a/pkg/psmdb/mongo/mongo_test.go b/pkg/psmdb/mongo/mongo_test.go index e2d36f3d26..0a022e5754 100644 --- a/pkg/psmdb/mongo/mongo_test.go +++ b/pkg/psmdb/mongo/mongo_test.go @@ -20,35 +20,55 @@ func TestVoting(t *testing.T) { { "3 mongos", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, }, }, { "2 mongos", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ Votes: 0, @@ -59,21 +79,34 @@ func TestVoting(t *testing.T) { { "2 mongos + 1 arbiter", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{ArbiterOnly: true}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: 0, + ArbiterOnly: true, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, + Votes: mongo.DefaultVotes, Priority: 0, }, }, @@ -81,66 +114,115 @@ func TestVoting(t *testing.T) { { "2 mongos + 1 first arbiter", &mongo.ConfigMembers{ - mongo.ConfigMember{ArbiterOnly: true}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: 0, + ArbiterOnly: true, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, + Votes: mongo.DefaultVotes, Priority: 0, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, }, }, { "9 mongos", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host3", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host4", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host5", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host6", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host7", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host8", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ Votes: 0, @@ -155,43 +237,75 @@ func TestVoting(t *testing.T) { { "8 mongos", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host3", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host4", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host5", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host6", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host7", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ Votes: 0, @@ -202,51 +316,88 @@ func TestVoting(t *testing.T) { { "8 mongos + 1 arbiter", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{ArbiterOnly: true}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host3", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host4", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host5", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host6", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host7", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host8", + Votes: mongo.DefaultVotes, + Priority: 0, + ArbiterOnly: true, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 0, - Priority: 0, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ Votes: 0, Priority: 0, }, mongo.ConfigMember{ - Votes: 1, + Votes: mongo.DefaultVotes, Priority: 0, }, }, @@ -254,26 +405,43 @@ func TestVoting(t *testing.T) { { "3 mongos + 1 arbiter", &mongo.ConfigMembers{ - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{}, - mongo.ConfigMember{ArbiterOnly: true}, + mongo.ConfigMember{ + Host: "host0", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host1", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host2", + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, + }, + mongo.ConfigMember{ + Host: "host3", + Votes: mongo.DefaultVotes, + Priority: 0, + ArbiterOnly: true, + }, }, &mongo.ConfigMembers{ mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ - Votes: 1, - Priority: 2, + Votes: mongo.DefaultVotes, + Priority: mongo.DefaultPriority, }, mongo.ConfigMember{ Votes: 0, Priority: 0, }, mongo.ConfigMember{ - Votes: 1, + Votes: mongo.DefaultVotes, Priority: 0, }, }, @@ -290,7 +458,7 @@ func TestVoting(t *testing.T) { for i, member := range *c.mset { d := []mongo.ConfigMember(*c.desiered) if member.Votes != d[i].Votes || member.Priority != d[i].Priority { - t.Errorf("%s: member %d want %v, have %v", c.name, i, d[i], member) + t.Errorf("%s: member (%s) want %v, have %v", c.name, member.Host, d[i], member) } } }