|
8 | 8 | "fmt"
|
9 | 9 | "image/color"
|
10 | 10 | "math/big"
|
| 11 | + prand "math/rand" |
11 | 12 | "net"
|
12 | 13 | "path/filepath"
|
13 | 14 | "regexp"
|
@@ -60,6 +61,18 @@ const (
|
60 | 61 | // durations exceeding this value will be eligible to have their
|
61 | 62 | // backoffs reduced.
|
62 | 63 | defaultStableConnDuration = 10 * time.Minute
|
| 64 | + |
| 65 | + // numInstantInitReconnect specifies how many persistent peers we should |
| 66 | + // always attempt outbound connections to immediately. After this value |
| 67 | + // is surpassed, the remaining peers will be randomly delayed using |
| 68 | + // maxInitReconnectDelay. |
| 69 | + numInstantInitReconnect = 10 |
| 70 | + |
| 71 | + // maxInitReconnectDelay specifies the maximum delay in seconds we will |
| 72 | + // apply in attempting to reconnect to persistent peers on startup. The |
| 73 | + // value used or a particular peer will be chosen between 0s and this |
| 74 | + // value. |
| 75 | + maxInitReconnectDelay = 30 |
63 | 76 | )
|
64 | 77 |
|
65 | 78 | var (
|
@@ -1932,6 +1945,7 @@ func (s *server) establishPersistentConnections() error {
|
1932 | 1945 |
|
1933 | 1946 | // Iterate through the combined list of addresses from prior links and
|
1934 | 1947 | // node announcements and attempt to reconnect to each node.
|
| 1948 | + var numOutboundConns int |
1935 | 1949 | for pubStr, nodeAddr := range nodeAddrsMap {
|
1936 | 1950 | // Add this peer to the set of peers we should maintain a
|
1937 | 1951 | // persistent connection with.
|
@@ -1962,13 +1976,42 @@ func (s *server) establishPersistentConnections() error {
|
1962 | 1976 | s.persistentConnReqs[pubStr] = append(
|
1963 | 1977 | s.persistentConnReqs[pubStr], connReq)
|
1964 | 1978 |
|
1965 |
| - go s.connMgr.Connect(connReq) |
| 1979 | + // We'll connect to the first 10 peers immediately, then |
| 1980 | + // randomly stagger any remaining connections if the |
| 1981 | + // stagger initial reconnect flag is set. This ensures |
| 1982 | + // that mobile nodes or nodes with a small number of |
| 1983 | + // channels obtain connectivity quickly, but larger |
| 1984 | + // nodes are able to disperse the costs of connecting to |
| 1985 | + // all peers at once. |
| 1986 | + if numOutboundConns < numInstantInitReconnect || |
| 1987 | + !cfg.StaggerInitialReconnect { |
| 1988 | + |
| 1989 | + go s.connMgr.Connect(connReq) |
| 1990 | + } else { |
| 1991 | + go s.delayInitialReconnect(connReq) |
| 1992 | + } |
1966 | 1993 | }
|
| 1994 | + |
| 1995 | + numOutboundConns++ |
1967 | 1996 | }
|
1968 | 1997 |
|
1969 | 1998 | return nil
|
1970 | 1999 | }
|
1971 | 2000 |
|
| 2001 | +// delayInitialReconnect will attempt a reconnection using the passed connreq |
| 2002 | +// after sampling a value for the delay between 0s and the |
| 2003 | +// maxInitReconnectDelay. |
| 2004 | +// |
| 2005 | +// NOTE: This method MUST be run as a goroutine. |
| 2006 | +func (s *server) delayInitialReconnect(connReq *connmgr.ConnReq) { |
| 2007 | + delay := time.Duration(prand.Intn(maxInitReconnectDelay)) * time.Second |
| 2008 | + select { |
| 2009 | + case <-time.After(delay): |
| 2010 | + s.connMgr.Connect(connReq) |
| 2011 | + case <-s.quit: |
| 2012 | + } |
| 2013 | +} |
| 2014 | + |
1972 | 2015 | // prunePersistentPeerConnection removes all internal state related to
|
1973 | 2016 | // persistent connections to a peer within the server. This is used to avoid
|
1974 | 2017 | // persistent connection retries to peers we do not have any open channels with.
|
|
0 commit comments