State of connection is now three-way choice rather than two booleans

This commit is contained in:
Bryan Boreham committed 2014-09-08 17:30:54 +01:00
1 parent f3cf2b598d
commit 64999d830d
2 files changed
+28 -25

No files matched your search

+24 -22
View File
@@ -16,10 +16,15 @@ const (
CMEnsure = iota
CMStatus = iota
CMEstablished = iota
CMConnSucceeded = iota
CMConnFailed = iota
)
const (
CMUnconnected ConnectionState = iota
CMAttempting = iota
CMEstablishedState = iota
)
func StartConnectionMaker(router *Router) *ConnectionMaker {
queryChan := make(chan *ConnectionMakerInteraction, ChannelSize)
state := &ConnectionMaker{
@@ -95,27 +100,23 @@ func (cm *ConnectionMaker) queryLoop(queryChan <-chan *ConnectionMakerInteractio
case query.code == CMEstablished:
target := cm.targets[query.address]
if target != nil {
target.established = true
target.state = CMEstablishedState
} else {
log.Fatal("Connection established to unknown address", query.address)
}
case query.code == CMConnSucceeded:
cm.targets[query.address].attempting = false
case query.code == CMConnFailed:
target := cm.targets[query.address]
target.attempting = false
after, interval := tryAfter(target.tryInterval)
target.tryInterval = interval
target.tryAfter = after
target.state = CMUnconnected
target.tryAfter, target.tryInterval = tryAfter(target.tryInterval)
maybeTick()
default:
log.Fatal("Unexpected connection maker query:", query)
}
case now := <-tick:
for address, target := range cm.targets {
if !target.established && !target.attempting && now.After(target.tryAfter) {
if target.state == CMUnconnected && now.After(target.tryAfter) {
target.attemptCount += 1
target.attempting = true
target.state = CMAttempting
go cm.attemptConnection(address, target.acceptAnyPeer)
}
}
@@ -129,6 +130,7 @@ func (cm *ConnectionMaker) addToTargets(acceptAnyPeer bool, address string) {
target := cm.targets[address]
if target == nil {
target = &Target{
state: CMUnconnected,
acceptAnyPeer: acceptAnyPeer,
}
cm.targets[address] = target
@@ -137,18 +139,21 @@ func (cm *ConnectionMaker) addToTargets(acceptAnyPeer bool, address string) {
func (cm *ConnectionMaker) resetTarget(address string) {
target := cm.targets[address]
target.established = false
after, interval := tryImmediately()
target.tryInterval = interval
target.tryAfter = after
// If we were in the middle of a connection attempt then back-off again
if target.state == CMAttempting {
target.tryAfter, target.tryInterval = tryAfter(target.tryInterval)
} else {
target.tryAfter, target.tryInterval = tryImmediately()
}
target.state = CMUnconnected
}
func (cm *ConnectionMaker) status() string {
var buf bytes.Buffer
for address, target := range cm.targets {
if target.established {
if target.state == CMEstablishedState {
buf.WriteString(fmt.Sprintf("%s connected\n", address))
} else if target.attempting {
} else if target.state == CMAttempting {
buf.WriteString(fmt.Sprintf("%s (%v attempts, trying since %v)\n", address, target.attemptCount, target.tryAfter))
} else {
buf.WriteString(fmt.Sprintf("%s (%v attempts, next at %v)\n", address, target.attemptCount, target.tryAfter))
@@ -159,15 +164,12 @@ func (cm *ConnectionMaker) status() string {
func (cm *ConnectionMaker) attemptConnection(address string, acceptNewPeer bool) {
log.Println("Attempting connection to", address)
var conncode = CMConnSucceeded
if err := cm.router.Ourself.CreateConnection(address, acceptNewPeer); err != nil {
log.Println(err)
conncode = CMConnFailed
cm.queryChan <- &ConnectionMakerInteraction{
Interaction: Interaction{code: CMConnFailed},
address: address}
}
// Tell the query loop we've finished this attempt
cm.queryChan <- &ConnectionMakerInteraction{
Interaction: Interaction{code: conncode},
address: address}
}
func tryImmediately() (time.Time, time.Duration) {
+4 -3
View File
@@ -165,11 +165,12 @@ type ConnectionMaker struct {
targets map[string]*Target
}
type ConnectionState int
// Information about an address where we may find a peer
type Target struct {
acceptAnyPeer bool // was this address given to us on the command line?
attempting bool // are we currently attempting to connect to this address?
established bool // has the connection been established
acceptAnyPeer bool // was this address given to us on the command line?
state ConnectionState
tryAfter time.Time // next time to try this address
tryInterval time.Duration // backoff time on next failure
attemptCount int