dir : consensus/state.go
defer 함수 선언
onExit := func(cs *State) {
if err := cs.wal.Stop(); err != nil {
//...
}
cs.wal.Wait()
close(cs.done)
}
recover 함수 선언
defer func() {
// 에러가 터져 receiveRoutine 함수가 종료될 것 같으면 defer로 빠져 recover를 시도
if r:= recover(); r != nil {
// ...
onExit(cs)
}
}()
채널을 열어 메시지 수신 대기
for {
if maxSteps > 0 {
if cs.nSteps >= maxSteps {
// maxSteps에 도달하면 리턴
cs.nSteps = 0
return
}
}
rs := cs.RoundState
var mi msgInfo
select {
// 정상적인 tx를 수신했을 경우
case <- cs.txNotifier.TxsAvailable():
cs.handleTxsAvailable()
// peer로부터 msg를 수신한 경우
case mi <- cs.peerMsgQueue:
// ...
// proposal, block parts, votes 등을 처리
// internal evt를 발생시킬 수 있다. (votes, prosoal 완료, 2/3 maj)
cs.handleMsg(mi)
// 동일 노드의 다른 곳에서 msg를 수신했을 경우
case mi = <- cs.internalMsgQueue:
// wal에 write
err := cs.wal.WriteSync(mi)
// ...
cs.handleMsg(mi)
// timeout에 도달한 경우
case ti := <- cs.timeoutTicker.Chan():
// ...
cs.handleTimeout(ti, rs)
// 노드를 정지할 경우 실행
case <- cs.Quit():
// ...
return
}
}