1.对于一个channel,如果是buffer的话,正确性不能因为buffer的大小而影响,这样不是个好设计,尽量使用没buffer的channel.
2.之所以之前用了buffer channel,是因为活锁问题。对于活锁可能导致的状态不一致,可以通过存临时变量来解决,当然这样要看情况。同时对于日志apply顺序的保障是一个apply协程来提交。然后apply snapshot在apply snapshot之后日志的保障是因为之前已经判断过 rf.Committed_Idx < args.LastIncludedIndex,并且只有锁,这就导致了leader不能append这个follower,也就不能改变commit_idx,结果就是apply停在了snapshot之前。这样就可以commit->snapshot -->commit这样的顺序的正确性。
3.channel特性:
这和applychannel不能上锁相呼应,给出了一定的保障。
我的bug:就是kvraft的server层,applyMessage 后面有三个commidMsg,然后一个InstallSnapshop Rpc 发送过来,要applySnapMsg,被阻塞,同时持有raft的锁,然后就deadlock 了,可以说gameover了。
4.apply次序问题:一个snapmsg插入到commitmsg里面,就导致了次序问题,因为后面改成channel前解锁了,为了解决这个问题,我用了单独的一把锁和一个变量来协调这个次序。