network: add a timer to check for peers
Consider initial connection phase for public networks: * simultaneous connections to seeds * very quick handshakes * got five handshaked peers and some getaddr requests sent * but addr replies won't trigger new connections * so we can stay with just five connections until any of them breaks or a (long) address checking timer fires This new timers solves the problem, it's adaptive at the same time. If we have enough peers we won't be waking up often.
This commit is contained in:
parent
23f118a1a9
commit
1c7487b8e4
1 changed files with 16 additions and 8 deletions
|
@ -400,10 +400,12 @@ func (s *Server) ConnectedPeers() []string {
|
||||||
func (s *Server) run() {
|
func (s *Server) run() {
|
||||||
var (
|
var (
|
||||||
peerCheckTime = s.TimePerBlock * peerTimeFactor
|
peerCheckTime = s.TimePerBlock * peerTimeFactor
|
||||||
peerCheckTimeout bool
|
addrCheckTimeout bool
|
||||||
timer = time.NewTimer(peerCheckTime)
|
addrTimer = time.NewTimer(peerCheckTime)
|
||||||
|
peerTimer = time.NewTimer(s.ProtoTickInterval)
|
||||||
)
|
)
|
||||||
defer timer.Stop()
|
defer addrTimer.Stop()
|
||||||
|
defer peerTimer.Stop()
|
||||||
go s.runProto()
|
go s.runProto()
|
||||||
for loopCnt := 0; ; loopCnt++ {
|
for loopCnt := 0; ; loopCnt++ {
|
||||||
var (
|
var (
|
||||||
|
@ -412,11 +414,15 @@ func (s *Server) run() {
|
||||||
optimalN = s.discovery.GetFanOut() * 2
|
optimalN = s.discovery.GetFanOut() * 2
|
||||||
// Real number of peers.
|
// Real number of peers.
|
||||||
peerN = s.HandshakedPeersCount()
|
peerN = s.HandshakedPeersCount()
|
||||||
|
// Timeout value for the next peerTimer, long one by default.
|
||||||
|
peerT = peerCheckTime
|
||||||
)
|
)
|
||||||
|
|
||||||
if peerN < s.MinPeers {
|
if peerN < s.MinPeers {
|
||||||
// Starting up or going below the minimum -> quickly get many new peers.
|
// Starting up or going below the minimum -> quickly get many new peers.
|
||||||
s.discovery.RequestRemote(s.AttemptConnPeers)
|
s.discovery.RequestRemote(s.AttemptConnPeers)
|
||||||
|
// Check/retry new connections soon.
|
||||||
|
peerT = s.ProtoTickInterval
|
||||||
} else if s.MinPeers > 0 && loopCnt%s.MinPeers == 0 && optimalN > peerN && optimalN < s.MaxPeers && optimalN < netSize {
|
} else if s.MinPeers > 0 && loopCnt%s.MinPeers == 0 && optimalN > peerN && optimalN < s.MaxPeers && optimalN < netSize {
|
||||||
// Having some number of peers, but probably can get some more, the network is big.
|
// Having some number of peers, but probably can get some more, the network is big.
|
||||||
// It also allows to start picking up new peers proactively, before we suddenly have <s.MinPeers of them.
|
// It also allows to start picking up new peers proactively, before we suddenly have <s.MinPeers of them.
|
||||||
|
@ -427,16 +433,18 @@ func (s *Server) run() {
|
||||||
s.discovery.RequestRemote(connN)
|
s.discovery.RequestRemote(connN)
|
||||||
}
|
}
|
||||||
|
|
||||||
if peerCheckTimeout || s.discovery.PoolCount() < s.AttemptConnPeers {
|
if addrCheckTimeout || s.discovery.PoolCount() < s.AttemptConnPeers {
|
||||||
s.broadcastHPMessage(NewMessage(CMDGetAddr, payload.NewNullPayload()))
|
s.broadcastHPMessage(NewMessage(CMDGetAddr, payload.NewNullPayload()))
|
||||||
peerCheckTimeout = false
|
addrCheckTimeout = false
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case <-s.quit:
|
case <-s.quit:
|
||||||
return
|
return
|
||||||
case <-timer.C:
|
case <-addrTimer.C:
|
||||||
peerCheckTimeout = true
|
addrCheckTimeout = true
|
||||||
timer.Reset(peerCheckTime)
|
addrTimer.Reset(peerCheckTime)
|
||||||
|
case <-peerTimer.C:
|
||||||
|
peerTimer.Reset(peerT)
|
||||||
case p := <-s.register:
|
case p := <-s.register:
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
s.peers[p] = true
|
s.peers[p] = true
|
||||||
|
|
Loading…
Reference in a new issue