@@ -23,7 +23,6 @@ type peerTracker struct {
23
23
24
24
peerLk sync.RWMutex
25
25
// trackedPeers contains active peers that we can request to.
26
- // we cache the peer once they disconnect,
27
26
// so we can guarantee that peerQueue will only contain active peers
28
27
trackedPeers map [libpeer.ID ]struct {}
29
28
@@ -101,72 +100,59 @@ func (p *peerTracker) connectToPeer(ctx context.Context, peer libpeer.ID) {
101
100
}
102
101
}
103
102
104
- func (p * peerTracker ) track () {
105
- defer func () {
106
- p .done <- struct {}{}
107
- }()
103
+ // track creates subscriptions for different types of libp2p.Events to efficiently handle peers.
104
+ func (p * peerTracker ) track () error {
105
+ evtBus := p .host .EventBus ()
108
106
109
- connSubs , err := p . host . EventBus () .Subscribe (& event.EvtPeerConnectednessChanged {})
107
+ connSubs , err := evtBus .Subscribe (& event.EvtPeerConnectednessChanged {})
110
108
if err != nil {
111
109
log .Errorw ("subscribing to EvtPeerConnectednessChanged" , "err" , err )
112
- return
110
+ return err
113
111
}
114
112
115
- identifySub , err := p . host . EventBus () .Subscribe (& event.EvtPeerIdentificationCompleted {})
113
+ identifySub , err := evtBus .Subscribe (& event.EvtPeerIdentificationCompleted {})
116
114
if err != nil {
117
115
log .Errorw ("subscribing to EvtPeerIdentificationCompleted" , "err" , err )
118
- return
116
+ return err
119
117
}
120
118
121
- protocolSub , err := p . host . EventBus () .Subscribe (& event.EvtPeerProtocolsUpdated {})
119
+ protocolSub , err := evtBus .Subscribe (& event.EvtPeerProtocolsUpdated {})
122
120
if err != nil {
123
121
log .Errorw ("subscribing to EvtPeerProtocolsUpdated" , "err" , err )
124
- return
122
+ return err
125
123
}
126
124
127
- for {
128
- select {
129
- case <- p .ctx .Done ():
130
- err = connSubs .Close ()
131
- errors .Join (err , identifySub .Close (), protocolSub .Close ())
132
- if err != nil {
133
- log .Errorw ("closing subscriptions" , "err" , err )
125
+ go func () {
126
+ for {
127
+ select {
128
+ case <- p .ctx .Done ():
129
+ if err := closeSubscriptions (connSubs , identifySub , protocolSub ); err != nil {
130
+ log .Errorw ("closing subscriptions" , "err" , err )
131
+ }
132
+ p .done <- struct {}{}
133
+ return
134
+ case connSubscription := <- connSubs .Out ():
135
+ ev := connSubscription .(event.EvtPeerConnectednessChanged )
136
+ if network .NotConnected == ev .Connectedness {
137
+ p .disconnected (ev .Peer )
138
+ }
139
+ case identSubscription := <- identifySub .Out ():
140
+ ev := identSubscription .(event.EvtPeerIdentificationCompleted )
141
+ if slices .Contains (ev .Protocols , p .protocolID ) {
142
+ p .connected (ev .Peer )
143
+ }
144
+ case protocolSubscription := <- protocolSub .Out ():
145
+ ev := protocolSubscription .(event.EvtPeerProtocolsUpdated )
146
+ if slices .Contains (ev .Removed , p .protocolID ) {
147
+ p .disconnected (ev .Peer )
148
+ }
149
+ if slices .Contains (ev .Added , p .protocolID ) {
150
+ p .connected (ev .Peer )
151
+ }
134
152
}
135
- return
136
- case connSubscription := <- connSubs .Out ():
137
- ev := connSubscription .(event.EvtPeerConnectednessChanged )
138
- if network .NotConnected == ev .Connectedness {
139
- p .disconnected (ev .Peer )
140
- }
141
- case identSubscription := <- identifySub .Out ():
142
- ev := identSubscription .(event.EvtPeerIdentificationCompleted )
143
- if slices .Contains (ev .Protocols , p .protocolID ) {
144
- p .connected (ev .Peer )
145
- }
146
- case protocolSubscription := <- protocolSub .Out ():
147
- ev := protocolSubscription .(event.EvtPeerProtocolsUpdated )
148
- if slices .Contains (ev .Removed , p .protocolID ) {
149
- p .disconnected (ev .Peer )
150
- break
151
- }
152
- p .connected (ev .Peer )
153
- }
154
- }
155
- }
156
-
157
- // getPeers returns the tracker's currently tracked peers up to the `max`.
158
- func (p * peerTracker ) getPeers (max int ) []libpeer.ID {
159
- p .peerLk .RLock ()
160
- defer p .peerLk .RUnlock ()
161
-
162
- peers := make ([]libpeer.ID , 0 , max )
163
- for peer := range p .trackedPeers {
164
- peers = append (peers , peer )
165
- if len (peers ) == max {
166
- break
167
153
}
168
- }
169
- return peers
154
+ }()
155
+ return nil
170
156
}
171
157
172
158
func (p * peerTracker ) connected (pID libpeer.ID ) {
@@ -215,17 +201,21 @@ func (p *peerTracker) disconnected(pID libpeer.ID) {
215
201
p .metrics .peersDisconnected (1 )
216
202
}
217
203
218
- func (p * peerTracker ) peers () []* peerStat {
204
+ // peers returns the tracker's currently tracked peers up to the `max`.
205
+ func (p * peerTracker ) peers (max int ) []* peerStat {
219
206
p .peerLk .RLock ()
220
207
defer p .peerLk .RUnlock ()
221
208
222
- peers := make ([]* peerStat , 0 )
209
+ peers := make ([]* peerStat , 0 , max )
223
210
for peerID := range p .trackedPeers {
224
211
score := 0
225
212
if info := p .host .ConnManager ().GetTagInfo (peerID ); info != nil {
226
213
score = info .Tags [string (p .protocolID )]
227
214
}
228
215
peers = append (peers , & peerStat {peerID : peerID , peerScore : score })
216
+ if len (peers ) == max {
217
+ break
218
+ }
229
219
}
230
220
return peers
231
221
}
@@ -296,3 +286,11 @@ func (p *peerTracker) updateScore(stats *peerStat, size uint64, duration time.Du
296
286
score := stats .updateStats (size , duration )
297
287
p .host .ConnManager ().TagPeer (stats .peerID , string (p .protocolID ), score )
298
288
}
289
+
290
+ func closeSubscriptions (subs ... event.Subscription ) error {
291
+ var err error
292
+ for _ , sub := range subs {
293
+ err = errors .Join (err , sub .Close ())
294
+ }
295
+ return err
296
+ }
0 commit comments