1
1
import { PeerSet } from '@libp2p/peer-collections'
2
- import map from 'it-map'
3
- import parallel from 'it-parallel'
4
- import { pipe } from 'it-pipe'
2
+ import { Queue } from '@libp2p/utils/queue'
3
+ import { pushable } from 'it-pushable'
5
4
import { ALPHA } from '../constants.js'
6
5
import { MessageType } from '../message/dht.js'
7
6
import { toPbPeerInfo } from '../message/utils.js'
@@ -10,7 +9,7 @@ import {
10
9
peerResponseEvent ,
11
10
providerEvent
12
11
} from '../query/events.js'
13
- import type { KadDHTComponents , PeerResponseEvent , ProviderEvent , QueryEvent } from '../index.js'
12
+ import type { FinalPeerEvent , KadDHTComponents , PeerResponseEvent , ProviderEvent , QueryEvent } from '../index.js'
14
13
import type { Message } from '../message/dht.js'
15
14
import type { Network } from '../network.js'
16
15
import type { PeerRouting } from '../peer-routing/index.js'
@@ -98,54 +97,76 @@ export class ContentRouting {
98
97
}
99
98
100
99
let sent = 0
100
+ const self = this
101
+
102
+ async function * publishProviderRecord ( event : FinalPeerEvent ) : AsyncGenerator < QueryEvent , void , undefined > {
103
+ try {
104
+ self . log ( 'sending provider record for %s to %p' , key , event . peer . id )
105
+
106
+ for await ( const addProviderEvent of self . network . sendMessage ( event . peer . id , msg , {
107
+ ...options ,
108
+ path : event . path
109
+ } ) ) {
110
+ if ( addProviderEvent . name === 'PEER_RESPONSE' ) {
111
+ self . log ( 'sent provider record for %s to %p' , key , event . peer . id )
112
+ sent ++
113
+ }
101
114
102
- const maybeNotifyPeer = ( event : QueryEvent ) => {
103
- return async ( ) => {
104
- if ( event . name !== 'FINAL_PEER' ) {
105
- return [ event ]
115
+ yield addProviderEvent
106
116
}
117
+ } catch ( err : any ) {
118
+ self . log . error ( 'error sending provide record to peer %p' , event . peer . id , err )
119
+ yield queryErrorEvent ( {
120
+ from : event . peer . id ,
121
+ error : err ,
122
+ path : event . path
123
+ } , options )
124
+ }
125
+ }
107
126
108
- const events = [ ]
127
+ const events = pushable < QueryEvent > ( {
128
+ objectMode : true
129
+ } )
109
130
110
- this . log ( 'putProvider %s to %p' , key , event . peer . id )
131
+ const queue = new Queue ( {
132
+ concurrency : ALPHA
133
+ } )
134
+ queue . addEventListener ( 'idle' , ( ) => {
135
+ events . end ( )
136
+ } )
137
+ queue . addEventListener ( 'error' , ( err ) => {
138
+ this . log . error ( 'error publishing provider record to peer - %e' , err )
139
+ } )
111
140
112
- try {
113
- this . log ( 'sending provider record for %s to %p' , key , event . peer . id )
114
-
115
- for await ( const sendEvent of this . network . sendMessage ( event . peer . id , msg , {
116
- ...options ,
117
- path : event . path ?? - 1
118
- } ) ) {
119
- if ( sendEvent . name === 'PEER_RESPONSE' ) {
120
- this . log ( 'sent provider record for %s to %p' , key , event . peer . id )
121
- sent ++
122
- }
123
-
124
- events . push ( sendEvent )
125
- }
126
- } catch ( err : any ) {
127
- this . log . error ( 'error sending provide record to peer %p' , event . peer . id , err )
128
- events . push ( queryErrorEvent ( { from : event . peer . id , error : err } , options ) )
129
- }
141
+ queue . add ( async ( ) => {
142
+ const finalPeerEvents : FinalPeerEvent [ ] = [ ]
130
143
131
- return events
132
- }
133
- }
144
+ for await ( const event of this . peerRouting . getClosestPeers ( target , options ) ) {
145
+ events . push ( event )
134
146
135
- // Notify closest peers
136
- yield * pipe (
137
- this . peerRouting . getClosestPeers ( target , options ) ,
138
- ( source ) => map ( source , ( event ) => maybeNotifyPeer ( event ) ) ,
139
- ( source ) => parallel ( source , {
140
- ordered : false ,
141
- concurrency : ALPHA
142
- } ) ,
143
- async function * ( source ) {
144
- for await ( const events of source ) {
145
- yield * events
147
+ if ( event . name !== 'FINAL_PEER' ) {
148
+ continue
146
149
}
150
+
151
+ finalPeerEvents . push ( event )
147
152
}
148
- )
153
+
154
+ finalPeerEvents . forEach ( event => {
155
+ queue . add ( async ( ) => {
156
+ for await ( const notifyEvent of publishProviderRecord ( event ) ) {
157
+ events . push ( notifyEvent )
158
+ }
159
+ } )
160
+ . catch ( err => {
161
+ this . log . error ( 'error publishing provider record to peer - %e' , err )
162
+ } )
163
+ } )
164
+ } )
165
+ . catch ( err => {
166
+ events . end ( err )
167
+ } )
168
+
169
+ yield * events
149
170
150
171
this . log ( 'sent provider records to %d peers' , sent )
151
172
}
@@ -184,8 +205,27 @@ export class ContentRouting {
184
205
}
185
206
}
186
207
187
- yield peerResponseEvent ( { from : this . components . peerId , messageType : MessageType . GET_PROVIDERS , providers, path : - 1 } , options )
188
- yield providerEvent ( { from : this . components . peerId , providers } , options )
208
+ yield peerResponseEvent ( {
209
+ from : this . components . peerId ,
210
+ messageType : MessageType . GET_PROVIDERS ,
211
+ providers,
212
+ path : {
213
+ index : - 1 ,
214
+ queued : 0 ,
215
+ running : 0 ,
216
+ total : 0
217
+ }
218
+ } , options )
219
+ yield providerEvent ( {
220
+ from : this . components . peerId ,
221
+ providers,
222
+ path : {
223
+ index : - 1 ,
224
+ queued : 0 ,
225
+ running : 0 ,
226
+ total : 0
227
+ }
228
+ } , options )
189
229
190
230
found += providers . length
191
231
@@ -203,7 +243,7 @@ export class ContentRouting {
203
243
key : target
204
244
}
205
245
206
- yield * self . network . sendRequest ( peer , request , {
246
+ yield * self . network . sendRequest ( peer . id , request , {
207
247
...options ,
208
248
signal,
209
249
path
@@ -230,7 +270,11 @@ export class ContentRouting {
230
270
}
231
271
232
272
if ( newProviders . length > 0 ) {
233
- yield providerEvent ( { from : event . from , providers : newProviders } , options )
273
+ yield providerEvent ( {
274
+ from : event . from ,
275
+ providers : newProviders ,
276
+ path : event . path
277
+ } , options )
234
278
235
279
found += newProviders . length
236
280
0 commit comments