eliminate periodic 'tick' in connection_maker

checkStateAndAttemptConnections already performs a full scan of all
potential targets, from which we can easily determine the nearest
future time (or, rather, its duration from now) on which an attempt is
due.

We also need to kick the ConnectionMaker into action when we receive a
topology update containing new connections.
This commit is contained in:
Matthias Radestock committed 2014-09-22 23:15:54 +01:00
1 parent d5e797f695
commit eecaa567fc
2 files changed
+26 -16

No files matched your search

+22 -16
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"log"
"math"
"math/rand"
"net"
"time"
@@ -17,6 +18,7 @@ const (
const (
CMInitiate = iota
CMTerminated = iota
CMRefresh = iota
CMStatus = iota
)
@@ -43,6 +45,11 @@ func (cm *ConnectionMaker) ConnectionTerminated(address string) {
address: address}
}
func (cm *ConnectionMaker) Refresh() {
cm.queryChan <- &ConnectionMakerInteraction{
Interaction: Interaction{code: CMRefresh}}
}
func (cm *ConnectionMaker) String() string {
resultChan := make(chan interface{}, 0)
cm.queryChan <- &ConnectionMakerInteraction{
@@ -52,12 +59,8 @@ func (cm *ConnectionMaker) String() string {
}
func (cm *ConnectionMaker) queryLoop(queryChan <-chan *ConnectionMakerInteraction) {
var tick <-chan time.Time
maybeTick := func() {
if tick == nil {
tick = time.After(5 * time.Second)
}
}
timer := time.NewTimer(math.MaxInt64)
run := func() { timer.Reset(cm.checkStateAndAttemptConnections()) }
for {
select {
case query, ok := <-queryChan:
@@ -67,29 +70,27 @@ func (cm *ConnectionMaker) queryLoop(queryChan <-chan *ConnectionMakerInteractio
switch query.code {
case CMInitiate:
cm.cmdLineAddress[NormalisePeerAddr(query.address)] = true
cm.checkStateAndAttemptConnections()
maybeTick()
run()
case CMTerminated:
if target, found := cm.targets[query.address]; found {
target.attempting = false
target.tryAfter, target.tryInterval = tryAfter(target.tryInterval)
}
cm.checkStateAndAttemptConnections()
maybeTick()
run()
case CMRefresh:
run()
case CMStatus:
query.resultChan <- cm.status()
default:
log.Fatal("Unexpected connection maker query:", query)
}
case <-tick:
cm.checkStateAndAttemptConnections()
tick = nil
maybeTick()
case <-timer.C:
run()
}
}
}
func (cm *ConnectionMaker) checkStateAndAttemptConnections() {
func (cm *ConnectionMaker) checkStateAndAttemptConnections() time.Duration {
ourself := cm.router.Ourself
validTarget := make(map[string]bool)
@@ -130,6 +131,7 @@ func (cm *ConnectionMaker) checkStateAndAttemptConnections() {
})
now := time.Now() // make sure we catch items just added
after := time.Duration(math.MaxInt64)
for address, target := range cm.targets {
if our_connected_targets[address] {
delete(cm.targets, address)
@@ -142,11 +144,15 @@ func (cm *ConnectionMaker) checkStateAndAttemptConnections() {
delete(cm.targets, address)
continue
}
if now.After(target.tryAfter) {
switch duration := target.tryAfter.Sub(now); {
case duration <= 0:
target.attempting = true
go cm.attemptConnection(address, cm.cmdLineAddress[address])
case duration < after:
after = duration
}
}
return after
}
func (cm *ConnectionMaker) addTarget(address string) {
+4
View File
@@ -77,6 +77,10 @@ func (cache *PeerCache) ApplyUpdate(update []byte, router *Router) ([]byte, erro
// Don't need to hold cache lock any longer
cache.Unlock()
if len(newUpdate) > 0 {
router.ConnectionMaker.Refresh()
}
return encodePeersMap(newUpdate), nil
}