Skip to content

Commit 3e515f0

Browse files
authored
fix: count dht providers and abort when enough found (#2470)
The way we were counting DHT providers was wrong, count the actual number found - this prevents queries continuing to execute after we've found K providers.
1 parent d446c6c commit 3e515f0

File tree

4 files changed

+25
-12
lines changed

4 files changed

+25
-12
lines changed

packages/kad-dht/src/content-routing/index.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ export class ContentRouting {
128128
*/
129129
async * findProviders (key: CID, options: RoutingOptions): AsyncGenerator<PeerResponseEvent | ProviderEvent | QueryEvent> {
130130
const toFind = this.routingTable.kBucketSize
131+
let found = 0
131132
const target = key.multihash.bytes
132133
const self = this // eslint-disable-line @typescript-eslint/no-this-alias
133134

@@ -158,11 +159,12 @@ export class ContentRouting {
158159

159160
yield peerResponseEvent({ from: this.components.peerId, messageType: MessageType.GET_PROVIDERS, providers }, options)
160161
yield providerEvent({ from: this.components.peerId, providers }, options)
161-
}
162162

163-
// All done
164-
if (provs.length >= toFind) {
165-
return
163+
found += providers.length
164+
165+
if (found >= toFind) {
166+
return
167+
}
166168
}
167169

168170
/**
@@ -201,10 +203,12 @@ export class ContentRouting {
201203

202204
if (newProviders.length > 0) {
203205
yield providerEvent({ from: event.from, providers: newProviders }, options)
204-
}
205206

206-
if (providers.size === toFind) {
207-
return
207+
found += newProviders.length
208+
209+
if (found >= toFind) {
210+
return
211+
}
208212
}
209213
}
210214
}

packages/kad-dht/src/query-self.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,11 @@ export class QuerySelf implements Startable {
106106

107107
if (this.started) {
108108
this.controller = new AbortController()
109-
const signal = anySignal([this.controller.signal, AbortSignal.timeout(this.queryTimeout)])
109+
const timeoutSignal = AbortSignal.timeout(this.queryTimeout)
110+
const signal = anySignal([this.controller.signal, timeoutSignal])
110111

111112
// this controller will get used for lots of dial attempts so make sure we don't cause warnings to be logged
112-
setMaxListeners(Infinity, signal)
113+
setMaxListeners(Infinity, signal, this.controller.signal, timeoutSignal)
113114

114115
try {
115116
if (this.routingTable.size === 0) {

packages/kad-dht/src/query/manager.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export interface QueryOptions extends RoutingOptions {
4848
export class QueryManager implements Startable {
4949
public disjointPaths: number
5050
private readonly alpha: number
51-
private readonly shutDownController: AbortController
51+
private shutDownController: AbortController
5252
private running: boolean
5353
private queries: number
5454
private readonly logger: ComponentLogger
@@ -96,6 +96,11 @@ export class QueryManager implements Startable {
9696
*/
9797
async start (): Promise<void> {
9898
this.running = true
99+
100+
// allow us to stop queries on shut down
101+
this.shutDownController = new AbortController()
102+
// make sure we don't make a lot of noise in the logs
103+
setMaxListeners(Infinity, this.shutDownController.signal)
99104
}
100105

101106
/**
@@ -131,7 +136,6 @@ export class QueryManager implements Startable {
131136
// if the user breaks out of a for..await of loop iterating over query
132137
// results we need to cancel any in-flight network requests
133138
const queryEarlyExitController = new AbortController()
134-
setMaxListeners(Infinity, queryEarlyExitController.signal)
135139

136140
const signal = anySignal([
137141
this.shutDownController.signal,
@@ -141,7 +145,7 @@ export class QueryManager implements Startable {
141145

142146
// this signal will get listened to for every invocation of queryFunc
143147
// so make sure we don't make a lot of noise in the logs
144-
setMaxListeners(Infinity, signal)
148+
setMaxListeners(Infinity, signal, queryEarlyExitController.signal)
145149

146150
const log = this.logger.forComponent(`${this.logPrefix}:query:` + uint8ArrayToString(key, 'base58btc'))
147151

packages/kad-dht/src/query/query-path.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { setMaxListeners } from '@libp2p/interface'
12
import { anySignal } from 'any-signal'
23
import Queue from 'p-queue'
34
import { toString } from 'uint8arrays/to-string'
@@ -112,6 +113,9 @@ export async function * queryPath (options: QueryPathOptions): AsyncGenerator<Qu
112113

113114
const compoundSignal = anySignal(signals)
114115

116+
// this signal can get listened to a lot
117+
setMaxListeners(Infinity, compoundSignal)
118+
115119
try {
116120
for await (const event of query({
117121
key,

0 commit comments

Comments
 (0)