influxdb/request_vote_request.go

78 lines
2.2 KiB
Go
Raw Normal View History

package raft
import (
"encoding/binary"
"io"
)
const requestVoteRequestHeaderSize = 4 + 8 + 8 + 8 + 4
// The request sent to a server to vote for a candidate to become a leader.
type RequestVoteRequest struct {
peer *Peer
Term uint64
LastLogIndex uint64
LastLogTerm uint64
CandidateName string
}
// Creates a new RequestVote request.
func newRequestVoteRequest(term uint64, candidateName string, lastLogIndex uint64, lastLogTerm uint64) *RequestVoteRequest {
return &RequestVoteRequest{
Term: term,
LastLogIndex: lastLogIndex,
LastLogTerm: lastLogTerm,
CandidateName: candidateName,
}
}
func (req *RequestVoteRequest) encode(w io.Writer) (int, error) {
candidateNameSize := len(req.CandidateName)
b := make([]byte, requestVoteRequestHeaderSize + candidateNameSize)
// Write request.
binary.BigEndian.PutUint32(b[0:4], protocolVersion)
binary.BigEndian.PutUint64(b[4:12], req.Term)
binary.BigEndian.PutUint64(b[12:20], req.LastLogIndex)
binary.BigEndian.PutUint64(b[20:28], req.LastLogTerm)
binary.BigEndian.PutUint32(b[28:32], uint32(candidateNameSize))
copy(b[32:], []byte(req.CandidateName))
return w.Write(b)
}
func (req *RequestVoteRequest) decode(r io.Reader) (int, error) {
var eof error
header := make([]byte, requestVoteRequestHeaderSize)
if n, err := r.Read(header); err == io.EOF {
return n, io.ErrUnexpectedEOF
} else if err != nil {
return n, err
}
// Read candidate name.
candidateName := make([]byte, binary.BigEndian.Uint32(header[28:32]))
if n, err := r.Read(candidateName); err == io.EOF {
if err == io.EOF && n != len(candidateName) {
return requestVoteRequestHeaderSize+n, io.ErrUnexpectedEOF
} else {
eof = io.EOF
}
} else if err != nil {
return requestVoteRequestHeaderSize+n, err
}
totalBytes := requestVoteRequestHeaderSize + len(candidateName)
// Verify that the encoding format can be read.
if version := binary.BigEndian.Uint32(header[0:4]); version != protocolVersion {
return totalBytes, errUnsupportedLogVersion
}
req.Term = binary.BigEndian.Uint64(header[4:12])
req.LastLogIndex = binary.BigEndian.Uint64(header[12:20])
req.LastLogTerm = binary.BigEndian.Uint64(header[20:28])
req.CandidateName = string(candidateName)
return totalBytes, eof
}