Skip to content

Commit e844d30

Browse files
lideljacobheun
authored andcommittedJul 24, 2019
fix: limit concurrent HTTP requests (#12)
All HTTP requests made by this module are sent to the same delegate host. Browsers throttle the number of concurrent requests per hostname, right now it is 6 per host, which suffocates the use of delegate and blocking it from being used for preload or delegated content routing. This introduces a task queue that limits the number of concurrent requests, making it safe to run in browser context. See also: libp2p/js-libp2p-delegated-content-routing#12 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
1 parent f09bf3d commit e844d30

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed
 

‎.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ docs
6161
.env
6262

6363
yarn.lock
64-
package-lock.json
64+
package-lock.json
65+
dist/

‎package.json

+2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
"ipfsd-ctl": "^0.44.1"
2626
},
2727
"dependencies": {
28+
"debug": "^4.1.1",
2829
"ipfs-http-client": "^33.1.0",
30+
"p-queue": "^6.1.0",
2931
"peer-id": "~0.12.2"
3032
},
3133
"contributors": [

‎src/index.js

+19-3
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,31 @@
33
const PeerId = require('peer-id')
44
const dht = require('ipfs-http-client/src/dht')
55
const defaultConfig = require('ipfs-http-client/src/utils/default-config')
6+
const { default: PQueue } = require('p-queue')
7+
const debug = require('debug')
8+
9+
const log = debug('libp2p-delegated-peer-routing')
10+
log.error = debug('libp2p-delegated-peer-routing:error')
611

712
const DEFAULT_MAX_TIMEOUT = 30e3 // 30 second default
813
const DEFAULT_IPFS_API = {
914
protocol: 'https',
1015
port: 443,
11-
host: 'ipfs.io'
16+
host: 'node0.delegate.ipfs.io'
1217
}
18+
const CONCURRENT_HTTP_REQUESTS = 4
1319

1420
class DelegatedPeerRouting {
1521
constructor (api) {
1622
this.api = Object.assign({}, defaultConfig(), DEFAULT_IPFS_API, api)
1723
this.dht = dht(this.api)
24+
25+
// limit concurrency to avoid request flood in web browser
26+
// https://github.com/libp2p/js-libp2p-delegated-content-routing/issues/12
27+
this._httpQueue = new PQueue({
28+
concurrency: CONCURRENT_HTTP_REQUESTS
29+
})
30+
log(`enabled DelegatedPeerRouting via ${this.api.protocol}://${this.api.host}:${this.api.port}`)
1831
}
1932

2033
/**
@@ -29,19 +42,22 @@ class DelegatedPeerRouting {
2942
if (PeerId.isPeerId(id)) {
3043
id = id.toB58String()
3144
}
45+
log('findPeer starts: ' + id)
3246

3347
options.maxTimeout = options.maxTimeout || DEFAULT_MAX_TIMEOUT
3448

3549
try {
36-
return await this.dht.findPeer(id, {
50+
return await this._httpQueue.add(() => this.dht.findPeer(id, {
3751
timeout: `${options.maxTimeout}ms`// The api requires specification of the time unit (s/ms)
38-
})
52+
}))
3953
} catch (err) {
4054
if (err.message.includes('not found')) {
4155
return undefined
4256
}
4357

4458
throw err
59+
} finally {
60+
log('findPeer finished: ' + id)
4561
}
4662
}
4763
}

‎test/index.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ describe('DelegatedPeerRouting', function () {
6464
})
6565

6666
describe('create', () => {
67-
it('should default to https://ipfs.io as the delegate', () => {
67+
it('should default to https://node0.delegate.ipfs.io as the delegate', () => {
6868
const router = new DelegatedPeerRouting()
6969

7070
expect(router.api).to.include({
7171
'api-path': '/api/v0/',
7272
protocol: 'https',
7373
port: 443,
74-
host: 'ipfs.io'
74+
host: 'node0.delegate.ipfs.io'
7575
})
7676
})
7777

0 commit comments

Comments
 (0)
Please sign in to comment.