Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make dialer configurable #521

Merged
merged 1 commit into from
Dec 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ Creates an instance of Libp2p.
| options | `Object` | libp2p options |
| options.modules | `Array<Object>` | libp2p modules to use |
| [options.config] | `Object` | libp2p modules configuration and core configuration |
| [options.connectionManager] | `Object` | libp2p Connection Manager configuration |
| [options.datastore] | `Object` | must implement [ipfs/interface-datastore](https://github.com/ipfs/interface-datastore) (in memory datastore will be used if not provided) |
| [options.dialer] | `Object` | libp2p Dialer configuration
| [options.metrics] | `Object` | libp2p Metrics configuration
| [options.peerInfo] | [PeerInfo](https://github.com/libp2p/js-peer-info) | peerInfo instance (it will be created if not provided) |

For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md).
Expand Down
24 changes: 24 additions & 0 deletions doc/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [Customizing DHT](#customizing-dht)
- [Setup with Content and Peer Routing](#setup-with-content-and-peer-routing)
- [Setup with Relay](#setup-with-relay)
- [Configuring Dialing](#configuring-dialing)
- [Configuring Connection Manager](#configuring-connection-manager)
- [Configuring Metrics](#configuring-metrics)
- [Configuration examples](#configuration-examples)
Expand Down Expand Up @@ -414,6 +415,29 @@ const node = await Libp2p.create({
})
```

#### Configuring Dialing

Dialing in libp2p can be configured to limit the rate of dialing, and how long dials are allowed to take. The below configuration example shows the default values for the dialer.

```js
const Libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const MPLEX = require('libp2p-mplex')
const SECIO = require('libp2p-secio')

const node = await Libp2p.create({
modules: {
transport: [TCP],
streamMuxer: [MPLEX],
connEncryption: [SECIO]
},
dialer: {
maxParallelDials: 100, // How many multiaddrs we can dial in parallel
maxDialsPerPeer: 4, // How many multiaddrs we can dial per peer, in parallel
dialTimeout: 30e3 // 30 second dial timeout per peer
}
```

#### Configuring Connection Manager

The Connection Manager prunes Connections in libp2p whenever certain limits are exceeded. If Metrics are enabled, you can also configure the Connection Manager to monitor the bandwidth of libp2p and prune connections as needed. You can read more about what Connection Manager does at [./CONNECTION_MANAGER.md](./CONNECTION_MANAGER.md). The configuration values below show the defaults for Connection Manager. See [./CONNECTION_MANAGER.md](./CONNECTION_MANAGER.md#options) for a full description of the parameters.
Expand Down
6 changes: 6 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
'use strict'

const mergeOptions = require('merge-options')
const Constants = require('./constants')

const DefaultConfig = {
connectionManager: {
minPeers: 25
},
dialer: {
maxParallelDials: Constants.MAX_PARALLEL_DIALS,
maxDialsPerPeer: Constants.MAX_PER_PEER_DIALS,
dialTimeout: Constants.DIAL_TIMEOUT
},
metrics: {
enabled: false
},
Expand Down
6 changes: 0 additions & 6 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
'use strict'

module.exports = {
DENY_TTL: 5 * 60 * 1e3, // How long before an errored peer can be dialed again
DENY_ATTEMPTS: 5, // Num of unsuccessful dials before a peer is permanently denied
DIAL_TIMEOUT: 30e3, // How long in ms a dial attempt is allowed to take
MAX_COLD_CALLS: 50, // How many dials w/o protocols that can be queued
MAX_PARALLEL_DIALS: 100, // Maximum allowed concurrent dials
MAX_PER_PEER_DIALS: 4, // Allowed parallel dials per DialRequest
QUARTER_HOUR: 15 * 60e3,
PRIORITY_HIGH: 10,
PRIORITY_LOW: 20,
METRICS: {
computeThrottleMaxQueueSize: 1000,
computeThrottleTimeout: 2000,
Expand Down
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ class Libp2p extends EventEmitter {

this.dialer = new Dialer({
transportManager: this.transportManager,
peerStore: this.peerStore
peerStore: this.peerStore,
concurrency: this._options.dialer.maxParallelDials,
perPeerLimit: this._options.dialer.maxDialsPerPeer,
timeout: this._options.dialer.dialTimeout
})

this._modules.transport.forEach((Transport) => {
Expand Down
25 changes: 25 additions & 0 deletions test/dialing/direct.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,35 @@ describe('Dialing (direct, WebSockets)', () => {
})

expect(libp2p.dialer).to.exist()
expect(libp2p.dialer.concurrency).to.equal(Constants.MAX_PARALLEL_DIALS)
expect(libp2p.dialer.perPeerLimit).to.equal(Constants.MAX_PER_PEER_DIALS)
expect(libp2p.dialer.timeout).to.equal(Constants.DIAL_TIMEOUT)
// Ensure the dialer also has the transport manager
expect(libp2p.transportManager).to.equal(libp2p.dialer.transportManager)
})

it('should be able to override dialer options', async () => {
const config = {
peerInfo,
modules: {
transport: [Transport],
streamMuxer: [Muxer],
connEncryption: [Crypto]
},
dialer: {
maxParallelDials: 10,
maxDialsPerPeer: 1,
dialTimeout: 1e3 // 30 second dial timeout per peer
}
}
libp2p = await Libp2p.create(config)

expect(libp2p.dialer).to.exist()
expect(libp2p.dialer.concurrency).to.equal(config.dialer.maxParallelDials)
expect(libp2p.dialer.perPeerLimit).to.equal(config.dialer.maxDialsPerPeer)
expect(libp2p.dialer.timeout).to.equal(config.dialer.dialTimeout)
})

it('should use the dialer for connecting', async () => {
libp2p = new Libp2p({
peerInfo,
Expand Down