Skip to content

Commit

Permalink
Merge pull request #2885 from cfromknecht/stagger-initial-reconnect
Browse files Browse the repository at this point in the history
server: stagger initial reconnects
  • Loading branch information
cfromknecht authored Apr 5, 2019
2 parents caa0e2f + cf80476 commit 25d2b1b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ type config struct {

RejectPush bool `long:"rejectpush" description:"If true, lnd will not accept channel opening requests with non-zero push amounts. This should prevent accidental pushes to merchant nodes."`

StaggerInitialReconnect bool `long:"stagger-initial-reconnect" description:"If true, will apply a randomized staggering between 0s and 30s when reconnecting to persistent peers on startup. The first 10 reconnections will be attempted instantly, regardless of the flag's value"`

net tor.Net

Routing *routing.Conf `group:"routing" namespace:"routing"`
Expand Down
45 changes: 44 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"image/color"
"math/big"
prand "math/rand"
"net"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -60,6 +61,18 @@ const (
// durations exceeding this value will be eligible to have their
// backoffs reduced.
defaultStableConnDuration = 10 * time.Minute

// numInstantInitReconnect specifies how many persistent peers we should
// always attempt outbound connections to immediately. After this value
// is surpassed, the remaining peers will be randomly delayed using
// maxInitReconnectDelay.
numInstantInitReconnect = 10

// maxInitReconnectDelay specifies the maximum delay in seconds we will
// apply in attempting to reconnect to persistent peers on startup. The
// value used or a particular peer will be chosen between 0s and this
// value.
maxInitReconnectDelay = 30
)

var (
Expand Down Expand Up @@ -1932,6 +1945,7 @@ func (s *server) establishPersistentConnections() error {

// Iterate through the combined list of addresses from prior links and
// node announcements and attempt to reconnect to each node.
var numOutboundConns int
for pubStr, nodeAddr := range nodeAddrsMap {
// Add this peer to the set of peers we should maintain a
// persistent connection with.
Expand Down Expand Up @@ -1962,13 +1976,42 @@ func (s *server) establishPersistentConnections() error {
s.persistentConnReqs[pubStr] = append(
s.persistentConnReqs[pubStr], connReq)

go s.connMgr.Connect(connReq)
// We'll connect to the first 10 peers immediately, then
// randomly stagger any remaining connections if the
// stagger initial reconnect flag is set. This ensures
// that mobile nodes or nodes with a small number of
// channels obtain connectivity quickly, but larger
// nodes are able to disperse the costs of connecting to
// all peers at once.
if numOutboundConns < numInstantInitReconnect ||
!cfg.StaggerInitialReconnect {

go s.connMgr.Connect(connReq)
} else {
go s.delayInitialReconnect(connReq)
}
}

numOutboundConns++
}

return nil
}

// delayInitialReconnect will attempt a reconnection using the passed connreq
// after sampling a value for the delay between 0s and the
// maxInitReconnectDelay.
//
// NOTE: This method MUST be run as a goroutine.
func (s *server) delayInitialReconnect(connReq *connmgr.ConnReq) {
delay := time.Duration(prand.Intn(maxInitReconnectDelay)) * time.Second
select {
case <-time.After(delay):
s.connMgr.Connect(connReq)
case <-s.quit:
}
}

// prunePersistentPeerConnection removes all internal state related to
// persistent connections to a peer within the server. This is used to avoid
// persistent connection retries to peers we do not have any open channels with.
Expand Down

0 comments on commit 25d2b1b

Please sign in to comment.