测试文件内容分析
func TestBasicAgree2B(t *testing.T) {
servers := 3
cfg := make_config(t, servers, false)
defer cfg.cleanup()
cfg.begin("Test (2B): basic agreement")
iters := 3
for index := 1; index < iters+1; index++ {
// 开始对应index处不应该有任何日志记录
nd, _ := cfg.nCommitted(index)
if nd > 0 {
t.Fatalf("some have committed before Start()")
}
// 调用start在里面创建日志记录,日志内容为index*100,并等待一段时间观察是否全部日志都已通过心跳发送到follower
xindex := cfg.one(index*100, servers, false)
if xindex != index {
t.Fatalf("got index %v but expected %v", xindex, index)
}
}
cfg.end()
}
go test使用技巧
执行语句为 go test -run 2B
这里run后面的参数会通过正则表达式与测试文件里出现过的全部测试函数名进行匹配,如果有重合部分就会执行,因此这里如果2B也可以写为B
如果只想针对某个测试函数进行debug,例如TestBasicAgree2B,可以改为:
go test -run TestBasicAgree2B
并发范式说明
for index, _ := range list {
go func(server int) {
fmt.Printf("%d\n", index) // 不应该为index,而是应为server
}(index)
}
因为前后写代码时间相隔较大,生疏了写法,在for循环里go func时仍然使用外部的index,而执行go func时index早已变成最大值,导致最后输出的全部内容一致
正确写法:go func里printf的index改为server
PartC部分主要错误原因
// 这里需要按照args的信息进行更新而不是直接更新,以防止因为网络延迟出现重复添加的问题
// rf.nextIndex[server] += len(args.Entries)
rf.nextIndex[server] = args.PrevLogIndex + len(args.Entries) + 1
rf.matchIndex[server] = rf.nextIndex[server] - 1
需要考虑网络延迟的问题
可能会出现nextIndex先出现100,再变回90的情况
也可能出现一个term类似情况,比如prev=4,len(logs)=90和prev=4,len(logs)=100发两次的情况,直接加会出现重复计算的问题