|
@@ -17,10 +17,10 @@ type Peer struct {
|
|
|
Name string `json:"name"`
|
|
Name string `json:"name"`
|
|
|
ConnectionString string `json:"connectionString"`
|
|
ConnectionString string `json:"connectionString"`
|
|
|
prevLogIndex uint64
|
|
prevLogIndex uint64
|
|
|
- mutex sync.RWMutex
|
|
|
|
|
stopChan chan bool
|
|
stopChan chan bool
|
|
|
heartbeatInterval time.Duration
|
|
heartbeatInterval time.Duration
|
|
|
lastActivity time.Time
|
|
lastActivity time.Time
|
|
|
|
|
+ sync.RWMutex
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------
|
|
@@ -56,18 +56,24 @@ func (p *Peer) setHeartbeatInterval(duration time.Duration) {
|
|
|
|
|
|
|
|
// Retrieves the previous log index.
|
|
// Retrieves the previous log index.
|
|
|
func (p *Peer) getPrevLogIndex() uint64 {
|
|
func (p *Peer) getPrevLogIndex() uint64 {
|
|
|
- p.mutex.RLock()
|
|
|
|
|
- defer p.mutex.RUnlock()
|
|
|
|
|
|
|
+ p.RLock()
|
|
|
|
|
+ defer p.RUnlock()
|
|
|
return p.prevLogIndex
|
|
return p.prevLogIndex
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Sets the previous log index.
|
|
// Sets the previous log index.
|
|
|
func (p *Peer) setPrevLogIndex(value uint64) {
|
|
func (p *Peer) setPrevLogIndex(value uint64) {
|
|
|
- p.mutex.Lock()
|
|
|
|
|
- defer p.mutex.Unlock()
|
|
|
|
|
|
|
+ p.Lock()
|
|
|
|
|
+ defer p.Unlock()
|
|
|
p.prevLogIndex = value
|
|
p.prevLogIndex = value
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (p *Peer) setLastActivity(now time.Time) {
|
|
|
|
|
+ p.Lock()
|
|
|
|
|
+ defer p.Unlock()
|
|
|
|
|
+ p.lastActivity = now
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
//------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------
|
|
|
//
|
|
//
|
|
|
// Methods
|
|
// Methods
|
|
@@ -93,6 +99,8 @@ func (p *Peer) stopHeartbeat(flush bool) {
|
|
|
|
|
|
|
|
// LastActivity returns the last time any response was received from the peer.
|
|
// LastActivity returns the last time any response was received from the peer.
|
|
|
func (p *Peer) LastActivity() time.Time {
|
|
func (p *Peer) LastActivity() time.Time {
|
|
|
|
|
+ p.RLock()
|
|
|
|
|
+ defer p.RUnlock()
|
|
|
return p.lastActivity
|
|
return p.lastActivity
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -103,8 +111,8 @@ func (p *Peer) LastActivity() time.Time {
|
|
|
// Clones the state of the peer. The clone is not attached to a server and
|
|
// Clones the state of the peer. The clone is not attached to a server and
|
|
|
// the heartbeat timer will not exist.
|
|
// the heartbeat timer will not exist.
|
|
|
func (p *Peer) clone() *Peer {
|
|
func (p *Peer) clone() *Peer {
|
|
|
- p.mutex.Lock()
|
|
|
|
|
- defer p.mutex.Unlock()
|
|
|
|
|
|
|
+ p.Lock()
|
|
|
|
|
+ defer p.Unlock()
|
|
|
return &Peer{
|
|
return &Peer{
|
|
|
Name: p.Name,
|
|
Name: p.Name,
|
|
|
ConnectionString: p.ConnectionString,
|
|
ConnectionString: p.ConnectionString,
|
|
@@ -181,9 +189,9 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
|
|
|
}
|
|
}
|
|
|
traceln("peer.append.resp: ", p.server.Name(), "<-", p.Name)
|
|
traceln("peer.append.resp: ", p.server.Name(), "<-", p.Name)
|
|
|
|
|
|
|
|
|
|
+ p.setLastActivity(time.Now())
|
|
|
// If successful then update the previous log index.
|
|
// If successful then update the previous log index.
|
|
|
- p.mutex.Lock()
|
|
|
|
|
- p.lastActivity = time.Now()
|
|
|
|
|
|
|
+ p.Lock()
|
|
|
if resp.Success() {
|
|
if resp.Success() {
|
|
|
if len(req.Entries) > 0 {
|
|
if len(req.Entries) > 0 {
|
|
|
p.prevLogIndex = req.Entries[len(req.Entries)-1].GetIndex()
|
|
p.prevLogIndex = req.Entries[len(req.Entries)-1].GetIndex()
|
|
@@ -229,7 +237,7 @@ func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
|
|
|
debugln("peer.append.resp.decrement: ", p.Name, "; idx =", p.prevLogIndex)
|
|
debugln("peer.append.resp.decrement: ", p.Name, "; idx =", p.prevLogIndex)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- p.mutex.Unlock()
|
|
|
|
|
|
|
+ p.Unlock()
|
|
|
|
|
|
|
|
// Attach the peer to resp, thus server can know where it comes from
|
|
// Attach the peer to resp, thus server can know where it comes from
|
|
|
resp.peer = p.Name
|
|
resp.peer = p.Name
|
|
@@ -251,7 +259,8 @@ func (p *Peer) sendSnapshotRequest(req *SnapshotRequest) {
|
|
|
|
|
|
|
|
// If successful, the peer should have been to snapshot state
|
|
// If successful, the peer should have been to snapshot state
|
|
|
// Send it the snapshot!
|
|
// Send it the snapshot!
|
|
|
- p.lastActivity = time.Now()
|
|
|
|
|
|
|
+ p.setLastActivity(time.Now())
|
|
|
|
|
+
|
|
|
if resp.Success {
|
|
if resp.Success {
|
|
|
p.sendSnapshotRecoveryRequest()
|
|
p.sendSnapshotRecoveryRequest()
|
|
|
} else {
|
|
} else {
|
|
@@ -272,7 +281,7 @@ func (p *Peer) sendSnapshotRecoveryRequest() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- p.lastActivity = time.Now()
|
|
|
|
|
|
|
+ p.setLastActivity(time.Now())
|
|
|
if resp.Success {
|
|
if resp.Success {
|
|
|
p.prevLogIndex = req.LastIndex
|
|
p.prevLogIndex = req.LastIndex
|
|
|
} else {
|
|
} else {
|
|
@@ -293,7 +302,7 @@ func (p *Peer) sendVoteRequest(req *RequestVoteRequest, c chan *RequestVoteRespo
|
|
|
req.peer = p
|
|
req.peer = p
|
|
|
if resp := p.server.Transporter().SendVoteRequest(p.server, p, req); resp != nil {
|
|
if resp := p.server.Transporter().SendVoteRequest(p.server, p, req); resp != nil {
|
|
|
debugln("peer.vote.recv: ", p.server.Name(), "<-", p.Name)
|
|
debugln("peer.vote.recv: ", p.server.Name(), "<-", p.Name)
|
|
|
- p.lastActivity = time.Now()
|
|
|
|
|
|
|
+ p.setLastActivity(time.Now())
|
|
|
resp.peer = p
|
|
resp.peer = p
|
|
|
c <- resp
|
|
c <- resp
|
|
|
} else {
|
|
} else {
|