@@ -9,6 +9,7 @@ import type { PeerStore } from '@libp2p/interface/peer-store'
9
9
import type { Topology } from '@libp2p/interface/topology'
10
10
import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
11
11
import type { StreamHandlerOptions , StreamHandlerRecord , Registrar , StreamHandler } from '@libp2p/interface-internal/registrar'
12
+ import { PeerSet } from '@libp2p/peer-collections'
12
13
13
14
const log = logger ( 'libp2p:registrar' )
14
15
@@ -26,11 +27,13 @@ export interface RegistrarComponents {
26
27
* Responsible for notifying registered protocols of events in the network.
27
28
*/
28
29
export class DefaultRegistrar implements Registrar {
30
+ private readonly topologyPeers : Map < string , PeerSet >
29
31
private readonly topologies : Map < string , Map < string , Topology > >
30
32
private readonly handlers : Map < string , StreamHandlerRecord >
31
33
private readonly components : RegistrarComponents
32
34
33
35
constructor ( components : RegistrarComponents ) {
36
+ this . topologyPeers = new Map ( )
34
37
this . topologies = new Map ( )
35
38
this . handlers = new Map ( )
36
39
this . components = components
@@ -130,6 +133,7 @@ export class DefaultRegistrar implements Registrar {
130
133
}
131
134
132
135
topologies . set ( id , topology )
136
+ this . topologyPeers . set ( id , new PeerSet ( ) )
133
137
134
138
return id
135
139
}
@@ -138,6 +142,7 @@ export class DefaultRegistrar implements Registrar {
138
142
* Unregister topology
139
143
*/
140
144
unregister ( id : string ) : void {
145
+ this . topologyPeers . delete ( id )
141
146
for ( const [ protocol , topologies ] of this . topologies . entries ( ) ) {
142
147
if ( topologies . has ( id ) ) {
143
148
topologies . delete ( id )
@@ -185,9 +190,8 @@ export class DefaultRegistrar implements Registrar {
185
190
*/
186
191
_onPeerUpdate ( evt : CustomEvent < PeerUpdate > ) : void {
187
192
const { peer, previous } = evt . detail
188
- const removed = ( previous ?. protocols ?? [ ] ) . filter ( protocol => ! peer . protocols . includes ( protocol ) )
189
- const added = peer . protocols . filter ( protocol => ! ( previous ?. protocols ?? [ ] ) . includes ( protocol ) )
190
193
194
+ const removed = ( previous ?. protocols ?? [ ] ) . filter ( protocol => ! peer . protocols . includes ( protocol ) )
191
195
for ( const protocol of removed ) {
192
196
const topologies = this . topologies . get ( protocol )
193
197
@@ -196,26 +200,47 @@ export class DefaultRegistrar implements Registrar {
196
200
continue
197
201
}
198
202
199
- for ( const topology of topologies . values ( ) ) {
200
- topology . onDisconnect ?.( peer . id )
203
+ for ( const [ id , topology ] of topologies . entries ( ) ) {
204
+ const peers = this . topologyPeers . get ( id )
205
+ if ( peers == null ) {
206
+ continue
207
+ }
208
+
209
+ for ( const peer of peers ) {
210
+ topology . onDisconnect ?.( peer )
211
+ }
212
+
213
+ peers . clear ( )
201
214
}
202
215
}
203
216
204
- for ( const protocol of added ) {
217
+ const connections = this . components . connectionManager . getConnections ( peer . id )
218
+ if ( connections . length === 0 ) {
219
+ return
220
+ }
221
+
222
+ const nonTransientConnection = connections . find ( ( connection ) => connection . transient === false )
223
+ for ( const protocol of peer . protocols ) {
205
224
const topologies = this . topologies . get ( protocol )
206
225
207
226
if ( topologies == null ) {
208
227
// no topologies are interested in this protocol
209
228
continue
210
229
}
211
230
212
- for ( const connection of this . components . connectionManager . getConnections ( peer . id ) ) {
213
- for ( const topology of topologies . values ( ) ) {
214
- if ( connection . transient && topology . notifyOnTransient !== true ) {
215
- continue
216
- }
231
+
232
+ for ( const [ id , topology ] of topologies . entries ( ) ) {
233
+ const peers = this . topologyPeers . get ( id )
234
+ if ( peers ?. has ( peer . id ) ) {
235
+ continue
236
+ }
217
237
218
- topology . onConnect ?.( peer . id , connection )
238
+ if ( topology . notifyOnTransient ) {
239
+ topology . onConnect ?.( peer . id , connections [ 0 ] )
240
+ peers ?. add ( peer . id )
241
+ } else if ( nonTransientConnection != null ) {
242
+ topology . onConnect ?.( peer . id , nonTransientConnection )
243
+ peers ?. add ( peer . id )
219
244
}
220
245
}
221
246
}
0 commit comments