State of connection is now three-way choice rather than two booleans
This commit is contained in:
1 parent
f3cf2b598d
commit
64999d830d
2 files changed
+28
-25
No files matched your search
+24
-22
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user