AI智能
改变未来

[etcd]raftpd confstate.go

_________________看前须知__________________

[code]message ConfState {// The voters in the incoming config. (If the configuration is not joint,// then the outgoing config is empty).repeated uint64 voters = 1;// The learners in the incoming config.repeated uint64 learners          = 2;// The voters in the outgoing config.repeated uint64 voters_outgoing   = 3;// The nodes that will become learners when the outgoing config is removed.// These nodes are necessarily currently in nodes_joint (or they would have// been added to the incoming config right away).repeated uint64 learners_next     = 4;// If set, the config is joint and Raft will automatically transition into// the final config (i.e. remove the outgoing config) when this is safe.optional bool   auto_leave        = 5 [(gogoproto.nullable) = false];}

这个是raftpd的proto文件中对于ConfState的结构定义,包括集群中的配置状态,voter、learner有多少个,移除了多少个voter等等。

在paxos中,Learners可以看做是所有被确认消息的执行器,一旦有Client的消息请求被Acceptors确认之后,Learners会做相应的处理(如:执行消息内容,发送回复给Client)。Learner可以有多个。Acceptor (Voters)可以看做是消息请求的存储器。一般来说Acceptors是由一定数量的服务组成的,当消息被发送给Acceptor, 只有大部分Acceptor确认接收此消息,该消息才会被存储,否则该消息将被丢弃。

_________________________________________

在confstate.go文件中只有如下一个函数,Equivalent函数,它是ConfState这个接口的一种方法,这个函数字面上理解就是相等,用于判断当前的confstate cs和传入的cs2这个confstate状态参数是否相等。相等就给error类型返回一个nil,表示没有错误;如果不相等就给error返回错误显示不同的地方在哪。其中用到了sort.Slice这个方法,就是一种排序的工具,这里i<j,就是从小到大的方式排序。

[code]// Equivalent returns a nil error if the inputs describe the same configuration.// On mismatch, returns a descriptive error showing the differences.func (cs ConfState) Equivalent(cs2 ConfState) error {cs1 := csorig1, orig2 := cs1, cs2s := func(sl *[]uint64) {*sl = append([]uint64(nil), *sl...)sort.Slice(*sl, func(i, j int) bool { return (*sl)[i] < (*sl)[j] })}for _, cs := range []*ConfState{&cs1, &cs2} {s(&cs.Voters)s(&cs.Learners)s(&cs.VotersOutgoing)s(&cs.LearnersNext)cs.XXX_unrecognized = nil}if !reflect.DeepEqual(cs1, cs2) {return fmt.Errorf(\"ConfStates not equivalent after sorting:\\n%+#v\\n%+#v\\nInputs were:\\n%+#v\\n%+#v\", cs1, cs2, orig1, orig2)}return nil}

下面我们来看看测试,首先定义一个测试案例的结构体, 包括两个参数,第一个是confstate状态参数,有2个state,第二个是是否相等的结果。

然后在测试案例中实例化一个testCases切片存储几种特殊的状态,看看那个Equivalent函数写的对不对,自己写了几种状态

case0:对于confstate中的值进行打乱顺序,但是值的相等的。

case1:对nil和empty的state不敏感

case2:不相等的voters

case3:不相等的learners

case4:对auto_leave  这个配置敏感

[code]func TestConfState_Equivalent(t *testing.T) {type testCase struct {cs, cs2 ConfStateok      bool}testCases := []testCase{// Reordered voters and learners.{ConfState{Voters:         []uint64{1, 2, 3},Learners:       []uint64{5, 4, 6},VotersOutgoing: []uint64{9, 8, 7},LearnersNext:   []uint64{10, 20, 15},}, ConfState{Voters:         []uint64{1, 2, 3},Learners:       []uint64{4, 5, 6},VotersOutgoing: []uint64{7, 9, 8},LearnersNext:   []uint64{20, 10, 15},}, true},// Not sensitive to nil vs empty slice.{ConfState{Voters: []uint64{}}, ConfState{Voters: []uint64(nil)}, true},// Non-equivalent voters.{ConfState{Voters: []uint64{1, 2, 3, 4}}, ConfState{Voters: []uint64{2, 1, 3}}, false},{ConfState{Voters: []uint64{1, 4, 3}}, ConfState{Voters: []uint64{2, 1, 3}}, false},// Non-equivalent learners.{ConfState{Voters: []uint64{1, 2, 3, 4}}, ConfState{Voters: []uint64{2, 1, 3}}, false},// Sensitive to AutoLeave flag.{ConfState{AutoLeave: true}, ConfState{}, false},}for _, tc := range testCases {t.Run(\"\", func(t *testing.T) {if err := tc.cs.Equivalent(tc.cs2); (err == nil) != tc.ok {t.Fatalf(\"wanted error: %t, got:\\n%s\", tc.ok, err)}})}}

 

 

 

 

 

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » [etcd]raftpd confstate.go