Skip to content
This repository was archived by the owner on Jul 21, 2023. It is now read-only.

Commit 0bef25f

Browse files
authored
feat: invoke onProgress callback if passed as an option (#472)
Send DHT query events to the onProgress callback if one is passed to allow operation-specific progress events to pass up the stack. Refs: libp2p/js-libp2p#1574
1 parent c17cbd7 commit 0bef25f

File tree

11 files changed

+175
-91
lines changed

11 files changed

+175
-91
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@
183183
"p-defer": "^4.0.0",
184184
"p-queue": "^7.3.4",
185185
"private-ip": "^3.0.0",
186+
"progress-events": "^1.0.0",
186187
"protons-runtime": "^5.0.0",
187188
"uint8arraylist": "^2.0.0",
188189
"uint8arrays": "^4.0.2",

src/content-fetching/index.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export class ContentFetching {
121121
}
122122

123123
if (!sentCorrection) {
124-
yield queryErrorEvent({ from, error: new CodeError('value not put correctly', 'ERR_PUT_VALUE_INVALID') })
124+
yield queryErrorEvent({ from, error: new CodeError('value not put correctly', 'ERR_PUT_VALUE_INVALID') }, options)
125125
}
126126

127127
this.log.error('Failed error correcting entry')
@@ -165,7 +165,7 @@ export class ContentFetching {
165165
}
166166

167167
if (!(putEvent.record != null && uint8ArrayEquals(putEvent.record.value, Libp2pRecord.deserialize(record).value))) {
168-
events.push(queryErrorEvent({ from: event.peer.id, error: new CodeError('value not put correctly', 'ERR_PUT_VALUE_INVALID') }))
168+
events.push(queryErrorEvent({ from: event.peer.id, error: new CodeError('value not put correctly', 'ERR_PUT_VALUE_INVALID') }, options))
169169
}
170170
}
171171

@@ -240,7 +240,7 @@ export class ContentFetching {
240240
yield valueEvent({
241241
value: localRec.value,
242242
from: this.components.peerId
243-
})
243+
}, options)
244244
} catch (err: any) {
245245
this.log('error getting local value for %b', key, err)
246246
}
@@ -252,7 +252,7 @@ export class ContentFetching {
252252
yield event
253253

254254
if (event.name === 'PEER_RESPONSE' && (event.record != null)) {
255-
yield valueEvent({ from: peer, value: event.record.value })
255+
yield valueEvent({ from: peer, value: event.record.value }, options)
256256
}
257257
}
258258
}

src/content-routing/index.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import type { QueryManager } from '../query/manager.js'
1717
import type { QueryFunc } from '../query/types.js'
1818
import type { RoutingTable } from '../routing-table/index.js'
1919
import type { PeerInfo } from '@libp2p/interface-peer-info'
20-
import type { AbortOptions } from '@libp2p/interfaces'
2120
import type { Logger } from '@libp2p/logger'
2221
import type { Multiaddr } from '@multiformats/multiaddr'
2322
import type { CID } from 'multiformats/cid'
@@ -56,7 +55,7 @@ export class ContentRouting {
5655
* Announce to the network that we can provide the value for a given key and
5756
* are contactable on the given multiaddrs
5857
*/
59-
async * provide (key: CID, multiaddrs: Multiaddr[], options: AbortOptions = {}): AsyncGenerator<QueryEvent, void, undefined> {
58+
async * provide (key: CID, multiaddrs: Multiaddr[], options: QueryOptions = {}): AsyncGenerator<QueryEvent, void, undefined> {
6059
this.log('provide %s', key)
6160

6261
// Add peer as provider
@@ -94,7 +93,7 @@ export class ContentRouting {
9493
}
9594
} catch (err: any) {
9695
this.log.error('error sending provide record to peer %p', event.peer.id, err)
97-
events.push(queryErrorEvent({ from: event.peer.id, error: err }))
96+
events.push(queryErrorEvent({ from: event.peer.id, error: err }, options))
9897
}
9998

10099
return events
@@ -153,8 +152,8 @@ export class ContentRouting {
153152
}
154153
}
155154

156-
yield peerResponseEvent({ from: this.components.peerId, messageType: MESSAGE_TYPE.GET_PROVIDERS, providers })
157-
yield providerEvent({ from: this.components.peerId, providers })
155+
yield peerResponseEvent({ from: this.components.peerId, messageType: MESSAGE_TYPE.GET_PROVIDERS, providers }, options)
156+
yield providerEvent({ from: this.components.peerId, providers }, options)
158157
}
159158

160159
// All done
@@ -168,7 +167,10 @@ export class ContentRouting {
168167
const findProvidersQuery: QueryFunc = async function * ({ peer, signal }) {
169168
const request = new Message(MESSAGE_TYPE.GET_PROVIDERS, target, 0)
170169

171-
yield * self.network.sendRequest(peer, request, { signal })
170+
yield * self.network.sendRequest(peer, request, {
171+
...options,
172+
signal
173+
})
172174
}
173175

174176
const providers = new Set(provs.map(p => p.toString()))
@@ -191,7 +193,7 @@ export class ContentRouting {
191193
}
192194

193195
if (newProviders.length > 0) {
194-
yield providerEvent({ from: event.from, providers: newProviders })
196+
yield providerEvent({ from: event.from, providers: newProviders }, options)
195197
}
196198

197199
if (providers.size === toFind) {

src/dual-kad-dht.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { queryErrorEvent } from './query/events.js'
1111
import type { DualKadDHT, KadDHT, KadDHTComponents, KadDHTInit, QueryEvent, QueryOptions } from './index.js'
1212
import type { PeerId } from '@libp2p/interface-peer-id'
1313
import type { PeerInfo } from '@libp2p/interface-peer-info'
14-
import type { AbortOptions } from '@libp2p/interfaces'
1514
import type { CID } from 'multiformats/cid'
1615

1716
const log = logger('libp2p:kad-dht')
@@ -26,23 +25,23 @@ class DHTContentRouting implements ContentRouting {
2625
this.dht = dht
2726
}
2827

29-
async provide (cid: CID): Promise<void> {
30-
await drain(this.dht.provide(cid))
28+
async provide (cid: CID, options: QueryOptions = {}): Promise<void> {
29+
await drain(this.dht.provide(cid, options))
3130
}
3231

33-
async * findProviders (cid: CID, options: AbortOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
32+
async * findProviders (cid: CID, options: QueryOptions = {}): AsyncGenerator<PeerInfo, void, undefined> {
3433
for await (const event of this.dht.findProviders(cid, options)) {
3534
if (event.name === 'PROVIDER') {
3635
yield * event.providers
3736
}
3837
}
3938
}
4039

41-
async put (key: Uint8Array, value: Uint8Array, options?: AbortOptions): Promise<void> {
40+
async put (key: Uint8Array, value: Uint8Array, options?: QueryOptions): Promise<void> {
4241
await drain(this.dht.put(key, value, options))
4342
}
4443

45-
async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
44+
async get (key: Uint8Array, options?: QueryOptions): Promise<Uint8Array> {
4645
for await (const event of this.dht.get(key, options)) {
4746
if (event.name === 'VALUE') {
4847
return event.value
@@ -63,7 +62,7 @@ class DHTPeerRouting implements PeerRouting {
6362
this.dht = dht
6463
}
6564

66-
async findPeer (peerId: PeerId, options: AbortOptions = {}): Promise<PeerInfo> {
65+
async findPeer (peerId: PeerId, options: QueryOptions = {}): Promise<PeerInfo> {
6766
for await (const event of this.dht.findPeer(peerId, options)) {
6867
if (event.name === 'FINAL_PEER') {
6968
return event.peer
@@ -73,7 +72,7 @@ class DHTPeerRouting implements PeerRouting {
7372
throw new CodeError('Not found', 'ERR_NOT_FOUND')
7473
}
7574

76-
async * getClosestPeers (key: Uint8Array, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
75+
async * getClosestPeers (key: Uint8Array, options: QueryOptions = {}): AsyncIterable<PeerInfo> {
7776
for await (const event of this.dht.getClosestPeers(key, options)) {
7877
if (event.name === 'FINAL_PEER') {
7978
yield event.peer
@@ -207,7 +206,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
207206
)) {
208207
yield event
209208

210-
if (event.name === 'DIALING_PEER') {
209+
if (event.name === 'DIAL_PEER') {
211210
queriedPeers = true
212211
}
213212

@@ -219,7 +218,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
219218
}
220219
}
221220

222-
if (event.name === 'SENDING_QUERY') {
221+
if (event.name === 'SEND_QUERY') {
223222
queriedPeers = true
224223
}
225224
}
@@ -232,7 +231,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
232231
yield queryErrorEvent({
233232
from: this.components.peerId,
234233
error: new CodeError('Not found', 'ERR_NOT_FOUND')
235-
})
234+
}, options)
236235
}
237236
}
238237

@@ -241,7 +240,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
241240
/**
242241
* Announce to the network that we can provide given key's value
243242
*/
244-
async * provide (key: CID, options: AbortOptions = {}): AsyncGenerator<QueryEvent> {
243+
async * provide (key: CID, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
245244
let sent = 0
246245
let success = 0
247246
const errors = []
@@ -256,7 +255,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
256255
for await (const event of merge(...dhts.map(dht => dht.provide(key, options)))) {
257256
yield event
258257

259-
if (event.name === 'SENDING_QUERY') {
258+
if (event.name === 'SEND_QUERY') {
260259
sent++
261260
}
262261

@@ -304,7 +303,7 @@ export class DefaultDualKadDHT extends EventEmitter<PeerDiscoveryEvents> impleme
304303
)) {
305304
yield event
306305

307-
if (event.name === 'SENDING_QUERY' || event.name === 'FINAL_PEER') {
306+
if (event.name === 'SEND_QUERY' || event.name === 'FINAL_PEER') {
308307
queriedPeers = true
309308
}
310309
}

src/index.ts

+25-14
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ import type { Registrar } from '@libp2p/interface-registrar'
1010
import type { AbortOptions } from '@libp2p/interfaces'
1111
import type { Datastore } from 'interface-datastore'
1212
import type { CID } from 'multiformats/cid'
13+
import type { ProgressOptions, ProgressEvent } from 'progress-events'
1314

1415
/**
1516
* The types of events emitted during DHT queries
1617
*/
1718
export enum EventTypes {
18-
SENDING_QUERY = 0,
19+
SEND_QUERY = 0,
1920
PEER_RESPONSE,
2021
FINAL_PEER,
2122
QUERY_ERROR,
2223
PROVIDER,
2324
VALUE,
24-
ADDING_PEER,
25-
DIALING_PEER
25+
ADD_PEER,
26+
DIAL_PEER
2627
}
2728

2829
/**
@@ -45,17 +46,27 @@ export interface DHTRecord {
4546
timeReceived?: Date
4647
}
4748

48-
export interface QueryOptions extends AbortOptions {
49+
export type DHTProgressEvents =
50+
ProgressEvent<'kad-dht:query:send-query', SendQueryEvent> |
51+
ProgressEvent<'kad-dht:query:peer-response', PeerResponseEvent> |
52+
ProgressEvent<'kad-dht:query:final-peer', FinalPeerEvent> |
53+
ProgressEvent<'kad-dht:query:query-error', QueryErrorEvent> |
54+
ProgressEvent<'kad-dht:query:provider', ProviderEvent> |
55+
ProgressEvent<'kad-dht:query:value', ValueEvent> |
56+
ProgressEvent<'kad-dht:query:add-peer', AddPeerEvent> |
57+
ProgressEvent<'kad-dht:query:dial-peer', DialPeerEvent>
58+
59+
export interface QueryOptions extends AbortOptions, ProgressOptions {
4960
queryFuncTimeout?: number
5061
}
5162

5263
/**
5364
* Emitted when sending queries to remote peers
5465
*/
55-
export interface SendingQueryEvent {
66+
export interface SendQueryEvent {
5667
to: PeerId
57-
type: EventTypes.SENDING_QUERY
58-
name: 'SENDING_QUERY'
68+
type: EventTypes.SEND_QUERY
69+
name: 'SEND_QUERY'
5970
messageName: keyof typeof MessageType
6071
messageType: MessageType
6172
}
@@ -118,22 +129,22 @@ export interface ValueEvent {
118129
/**
119130
* Emitted when peers are added to a query
120131
*/
121-
export interface AddingPeerEvent {
122-
type: EventTypes.ADDING_PEER
123-
name: 'ADDING_PEER'
132+
export interface AddPeerEvent {
133+
type: EventTypes.ADD_PEER
134+
name: 'ADD_PEER'
124135
peer: PeerId
125136
}
126137

127138
/**
128139
* Emitted when peers are dialled as part of a query
129140
*/
130-
export interface DialingPeerEvent {
141+
export interface DialPeerEvent {
131142
peer: PeerId
132-
type: EventTypes.DIALING_PEER
133-
name: 'DIALING_PEER'
143+
type: EventTypes.DIAL_PEER
144+
name: 'DIAL_PEER'
134145
}
135146

136-
export type QueryEvent = SendingQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddingPeerEvent | DialingPeerEvent
147+
export type QueryEvent = SendQueryEvent | PeerResponseEvent | FinalPeerEvent | QueryErrorEvent | ProviderEvent | ValueEvent | AddPeerEvent | DialPeerEvent
137148

138149
export interface RoutingTable {
139150
size: number

src/network.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import * as lp from 'it-length-prefixed'
88
import { pipe } from 'it-pipe'
99
import { Message } from './message/index.js'
1010
import {
11-
dialingPeerEvent,
12-
sendingQueryEvent,
11+
dialPeerEvent,
12+
sendQueryEvent,
1313
peerResponseEvent,
1414
queryErrorEvent
1515
} from './query/events.js'
16-
import type { KadDHTComponents, QueryEvent } from './index.js'
16+
import type { KadDHTComponents, QueryEvent, QueryOptions } from './index.js'
1717
import type { Stream } from '@libp2p/interface-connection'
1818
import type { PeerId } from '@libp2p/interface-peer-id'
1919
import type { PeerInfo } from '@libp2p/interface-peer-info'
@@ -82,14 +82,14 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
8282
/**
8383
* Send a request and record RTT for latency measurements
8484
*/
85-
async * sendRequest (to: PeerId, msg: Message, options: AbortOptions = {}): AsyncGenerator<QueryEvent> {
85+
async * sendRequest (to: PeerId, msg: Message, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
8686
if (!this.running) {
8787
return
8888
}
8989

9090
this.log('sending %s to %p', msg.type, to)
91-
yield dialingPeerEvent({ peer: to })
92-
yield sendingQueryEvent({ to, type: msg.type })
91+
yield dialPeerEvent({ peer: to }, options)
92+
yield sendQueryEvent({ to, type: msg.type }, options)
9393

9494
let stream: Stream | undefined
9595

@@ -105,9 +105,9 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
105105
closer: response.closerPeers,
106106
providers: response.providerPeers,
107107
record: response.record
108-
})
108+
}, options)
109109
} catch (err: any) {
110-
yield queryErrorEvent({ from: to, error: err })
110+
yield queryErrorEvent({ from: to, error: err }, options)
111111
} finally {
112112
if (stream != null) {
113113
stream.close()
@@ -118,14 +118,14 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
118118
/**
119119
* Sends a message without expecting an answer
120120
*/
121-
async * sendMessage (to: PeerId, msg: Message, options: AbortOptions = {}): AsyncGenerator<QueryEvent> {
121+
async * sendMessage (to: PeerId, msg: Message, options: QueryOptions = {}): AsyncGenerator<QueryEvent> {
122122
if (!this.running) {
123123
return
124124
}
125125

126126
this.log('sending %s to %p', msg.type, to)
127-
yield dialingPeerEvent({ peer: to })
128-
yield sendingQueryEvent({ to, type: msg.type })
127+
yield dialPeerEvent({ peer: to }, options)
128+
yield sendQueryEvent({ to, type: msg.type }, options)
129129

130130
let stream: Stream | undefined
131131

@@ -135,9 +135,9 @@ export class Network extends EventEmitter<NetworkEvents> implements Startable {
135135

136136
await this._writeMessage(stream, msg.serialize(), options)
137137

138-
yield peerResponseEvent({ from: to, messageType: msg.type })
138+
yield peerResponseEvent({ from: to, messageType: msg.type }, options)
139139
} catch (err: any) {
140-
yield queryErrorEvent({ from: to, error: err })
140+
yield queryErrorEvent({ from: to, error: err }, options)
141141
} finally {
142142
if (stream != null) {
143143
stream.close()

0 commit comments

Comments
 (0)