Skip to content

Commit 62e71d0

Browse files
author
ScottyPoi
committed
ContentLookup: use AbortController to prevent hanging requests
1 parent 1c4fe39 commit 62e71d0

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

packages/portalnetwork/src/networks/contentLookup.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,15 @@ export class ContentLookup {
9292
peerBatch.push(next)
9393
}
9494
const promises = peerBatch.map((peer) => {
95+
const controller = new AbortController()
96+
const timeoutId = setTimeout(() => {
97+
controller.abort()
98+
}, this.timeout)
99+
95100
return Promise.race([
96-
this.processPeer(peer),
101+
this.processPeer(peer, controller.signal).finally(() => {
102+
clearTimeout(timeoutId)
103+
}),
97104
new Promise((resolve) =>
98105
setTimeout(() => {
99106
resolve(undefined)
@@ -156,7 +163,7 @@ export class ContentLookup {
156163
return this.content
157164
}
158165

159-
private processPeer = async (peer: LookupPeer): Promise<ContentLookupResponse | void> => {
166+
private processPeer = async (peer: LookupPeer, signal?: AbortSignal): Promise<ContentLookupResponse | void> => {
160167
if (this.finished) return
161168
if (this.network.routingTable.isIgnored(peer.enr.nodeId)) {
162169
this.logger(`peer ${shortId(peer.enr.nodeId)} is ignored`)
@@ -166,7 +173,21 @@ export class ContentLookup {
166173
this.pending.add(peer.enr.encodeTxt())
167174
this.logger(`Requesting content from ${shortId(peer.enr.nodeId)}`)
168175
try {
169-
const res = await this.network.sendFindContent!(peer.enr, this.contentKey)
176+
// Create a promise that rejects when the signal is aborted
177+
const abortPromise = new Promise((_, reject) => {
178+
if (signal) {
179+
signal.addEventListener('abort', () => {
180+
reject(new Error('Request cancelled'))
181+
})
182+
}
183+
})
184+
185+
// Race between the actual request and the abort signal
186+
const res = await Promise.race([
187+
this.network.sendFindContent!(peer.enr, this.contentKey),
188+
abortPromise
189+
]) as ContentLookupResponse | undefined
190+
170191
this.pending.delete(peer.enr.encodeTxt())
171192
if (this.finished) {
172193
this.logger(`Response from ${shortId(peer.enr.nodeId)} arrived after lookup finished`)
@@ -219,6 +240,9 @@ export class ContentLookup {
219240
}
220241
} catch (err) {
221242
this.pending.delete(peer.enr.encodeTxt())
243+
if (signal?.aborted) {
244+
this.logger(`Request to ${shortId(peer.enr.nodeId)} was cancelled`)
245+
}
222246
throw err
223247
}
224248
}

0 commit comments

Comments
 (0)