44
44
// add loop back in Dial(.)
45
45
const dialAttempts = 1
46
46
47
+ // dial at most 12 peers concurrently
48
+ const concurrentPeerDials = 12
49
+
47
50
// DialTimeout is the amount of time each dial attempt has. We can think about making
48
51
// this larger down the road, or putting more granular timeouts (i.e. within each
49
52
// subcomponent of Dial)
@@ -77,6 +80,8 @@ type dialsync struct {
77
80
// this way, we dont kick off N dials simultaneously.
78
81
ongoing map [peer.ID ]chan struct {}
79
82
lock sync.Mutex
83
+
84
+ ratelimit chan struct {}
80
85
}
81
86
82
87
// Lock governs the beginning of a dial attempt.
@@ -92,6 +97,7 @@ func (ds *dialsync) Lock(dst peer.ID) (bool, chan struct{}) {
92
97
ds .lock .Lock ()
93
98
if ds .ongoing == nil { // init if not ready
94
99
ds .ongoing = make (map [peer.ID ]chan struct {})
100
+ ds .ratelimit = make (chan struct {}, concurrentPeerDials )
95
101
}
96
102
wait , found := ds .ongoing [dst ]
97
103
if ! found {
@@ -103,6 +109,9 @@ func (ds *dialsync) Lock(dst peer.ID) (bool, chan struct{}) {
103
109
return false , wait
104
110
}
105
111
112
+ // consume rate limiting token
113
+ ds .ratelimit <- struct {}{}
114
+
106
115
// ok! you're signed up to dial!
107
116
return true , nil
108
117
}
@@ -115,6 +124,10 @@ func (ds *dialsync) Unlock(dst peer.ID) {
115
124
if ! found {
116
125
panic ("called dialDone with no ongoing dials to peer: " + dst .Pretty ())
117
126
}
127
+
128
+ // replace token for rate limiting
129
+ <- ds .ratelimit
130
+
118
131
delete (ds .ongoing , dst ) // remove ongoing dial
119
132
close (wait ) // release everyone else
120
133
ds .lock .Unlock ()
0 commit comments