Skip to content

Commit 0218acf

Browse files
authored
fix: report dialer metrics (#1377)
Converts the dialer to a component so it can access metrics
1 parent b87632f commit 0218acf

8 files changed

Lines changed: 54 additions & 82 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@
9898
},
9999
"dependencies": {
100100
"@achingbrain/nat-port-mapper": "^1.0.3",
101-
"@libp2p/components": "^2.0.3",
101+
"@libp2p/components": "^2.1.0",
102102
"@libp2p/connection": "^4.0.1",
103103
"@libp2p/crypto": "^1.0.3",
104104
"@libp2p/interface-address-manager": "^1.0.2",
105105
"@libp2p/interface-connection": "^3.0.1",
106106
"@libp2p/interface-connection-encrypter": "^2.0.1",
107+
"@libp2p/interface-connection-manager": "^1.1.0",
107108
"@libp2p/interface-content-routing": "^1.0.2",
108109
"@libp2p/interface-dht": "^1.0.1",
109110
"@libp2p/interface-metrics": "^3.0.0",

src/connection-manager/dialer/dial-request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { logger } from '@libp2p/logger'
77
import type { Multiaddr } from '@multiformats/multiaddr'
88
import type { Connection } from '@libp2p/interface-connection'
99
import type { AbortOptions } from '@libp2p/interfaces'
10-
import type { Dialer } from './index.js'
10+
import type { Dialer } from '@libp2p/interface-connection-manager'
1111

1212
const log = logger('libp2p:dialer:dial-request')
1313

src/connection-manager/dialer/index.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ import type { Startable } from '@libp2p/interfaces/startable'
2424
import type { PeerId } from '@libp2p/interface-peer-id'
2525
import { getPeer } from '../../get-peer.js'
2626
import sort from 'it-sort'
27-
import { Components, Initializable } from '@libp2p/components'
27+
import type { Components } from '@libp2p/components'
2828
import map from 'it-map'
2929
import type { AddressSorter } from '@libp2p/interface-peer-store'
3030
import type { ComponentMetricsTracker } from '@libp2p/interface-metrics'
31+
import type { Dialer } from '@libp2p/interface-connection-manager'
3132

3233
const log = logger('libp2p:dialer')
3334

@@ -85,8 +86,8 @@ export interface DialerInit {
8586
metrics?: ComponentMetricsTracker
8687
}
8788

88-
export class Dialer implements Startable, Initializable {
89-
private components: Components = new Components()
89+
export class DefaultDialer implements Startable, Dialer {
90+
private readonly components: Components
9091
private readonly addressSorter: AddressSorter
9192
private readonly maxAddrsToDial: number
9293
private readonly timeout: number
@@ -96,13 +97,14 @@ export class Dialer implements Startable, Initializable {
9697
public pendingDialTargets: Map<string, PendingDialTarget>
9798
private started: boolean
9899

99-
constructor (init: DialerInit = {}) {
100+
constructor (components: Components, init: DialerInit = {}) {
100101
this.started = false
101102
this.addressSorter = init.addressSorter ?? publicAddressesFirst
102103
this.maxAddrsToDial = init.maxAddrsToDial ?? MAX_ADDRS_TO_DIAL
103104
this.timeout = init.dialTimeout ?? DIAL_TIMEOUT
104105
this.maxDialsPerPeer = init.maxDialsPerPeer ?? MAX_PER_PEER_DIALS
105106
this.tokens = [...new Array(init.maxParallelDials ?? MAX_PARALLEL_DIALS)].map((_, index) => index)
107+
this.components = components
106108
this.pendingDials = trackedMap({
107109
component: METRICS_COMPONENT,
108110
metric: METRICS_PENDING_DIALS,
@@ -111,18 +113,14 @@ export class Dialer implements Startable, Initializable {
111113
this.pendingDialTargets = trackedMap({
112114
component: METRICS_COMPONENT,
113115
metric: METRICS_PENDING_DIAL_TARGETS,
114-
metrics: init.metrics
116+
metrics: components.getMetrics()
115117
})
116118

117119
for (const [key, value] of Object.entries(init.resolvers ?? {})) {
118120
Multiaddr.resolvers.set(key, value)
119121
}
120122
}
121123

122-
init (components: Components): void {
123-
this.components = components
124-
}
125-
126124
isStarted () {
127125
return this.started
128126
}

src/connection-manager/index.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import type { Connection } from '@libp2p/interface-connection'
1414
import type { ConnectionManager } from '@libp2p/interface-connection-manager'
1515
import { Components, Initializable } from '@libp2p/components'
1616
import * as STATUS from '@libp2p/interface-connection/status'
17-
import { Dialer } from './dialer/index.js'
1817
import type { AddressSorter } from '@libp2p/interface-peer-store'
1918
import type { Resolver } from '@multiformats/multiaddr'
2019
import { PeerMap } from '@libp2p/peer-collections'
@@ -144,7 +143,6 @@ export interface ConnectionManagerEvents {
144143
* Responsible for managing known connections.
145144
*/
146145
export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEvents> implements ConnectionManager, Startable, Initializable {
147-
public readonly dialer: Dialer
148146
private components = new Components()
149147
private readonly opts: Required<ConnectionManagerInit>
150148
private readonly connections: Map<string, Connection[]>
@@ -184,8 +182,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
184182
setMaxListeners?.(Infinity, this)
185183
} catch {}
186184

187-
this.dialer = new Dialer(this.opts)
188-
189185
this.onConnect = this.onConnect.bind(this)
190186
this.onDisconnect = this.onDisconnect.bind(this)
191187

@@ -196,8 +192,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
196192
init (components: Components): void {
197193
this.components = components
198194

199-
this.dialer.init(components)
200-
201195
// track inbound/outbound connections
202196
this.components.getMetrics()?.updateComponentMetric({
203197
system: METRICS_SYSTEM,
@@ -304,7 +298,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
304298
this.latencyMonitor.start()
305299
this._onLatencyMeasure = this._onLatencyMeasure.bind(this)
306300
this.latencyMonitor.addEventListener('data', this._onLatencyMeasure)
307-
await this.dialer.start()
308301

309302
this.started = true
310303
log('started')
@@ -370,7 +363,6 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
370363

371364
this.latencyMonitor.removeEventListener('data', this._onLatencyMeasure)
372365
this.latencyMonitor.stop()
373-
await this.dialer.stop()
374366

375367
this.started = false
376368
await this._close()
@@ -526,7 +518,7 @@ export class DefaultConnectionManager extends EventEmitter<ConnectionManagerEven
526518
}
527519

528520
try {
529-
const connection = await this.dialer.dial(peerId, options)
521+
const connection = await this.components.getDialer().dial(peerId, options)
530522
let peerConnections = this.connections.get(peerId.toString())
531523

532524
if (peerConnections == null) {

src/libp2p.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import type { Metrics } from '@libp2p/interface-metrics'
4949
import { DummyDHT } from './dht/dummy-dht.js'
5050
import { DummyPubSub } from './pubsub/dummy-pubsub.js'
5151
import { PeerSet } from '@libp2p/peer-collections'
52+
import { DefaultDialer } from './connection-manager/dialer/index.js'
5253

5354
const log = logger('libp2p')
5455

@@ -128,6 +129,9 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
128129
inboundUpgradeTimeout: init.connectionManager.inboundUpgradeTimeout
129130
}))
130131

132+
// Create the dialer
133+
this.components.setDialer(new DefaultDialer(this.components, init.connectionManager))
134+
131135
// Create the Connection Manager
132136
this.connectionManager = this.components.setConnectionManager(new DefaultConnectionManager(init.connectionManager))
133137

@@ -338,7 +342,7 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
338342
)
339343

340344
await Promise.all(
341-
this.services.map(servce => servce.stop())
345+
this.services.map(service => service.stop())
342346
)
343347

344348
await Promise.all(

test/dialing/dial-request.spec.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { DialAction, DialRequest } from '../../src/connection-manager/dialer/dia
99
import { mockConnection, mockDuplex, mockMultiaddrConnection } from '@libp2p/interface-mocks'
1010
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
1111
import { Multiaddr } from '@multiformats/multiaddr'
12-
import { Dialer } from '../../src/connection-manager/dialer/index.js'
12+
import { DefaultDialer } from '../../src/connection-manager/dialer/index.js'
13+
import { Components } from '@libp2p/components'
1314
const error = new Error('dial failure')
1415

1516
describe('Dial Request', () => {
@@ -23,7 +24,7 @@ describe('Dial Request', () => {
2324
}
2425
const dialAction: DialAction = async (num) => await actions[num.toString()]()
2526
const controller = new AbortController()
26-
const dialer = new Dialer({
27+
const dialer = new DefaultDialer(new Components(), {
2728
maxParallelDials: 2
2829
})
2930
const dialerReleaseTokenSpy = sinon.spy(dialer, 'releaseToken')
@@ -53,7 +54,7 @@ describe('Dial Request', () => {
5354
}
5455
const dialAction: DialAction = async (num) => await actions[num.toString()]()
5556
const controller = new AbortController()
56-
const dialer = new Dialer({
57+
const dialer = new DefaultDialer(new Components(), {
5758
maxParallelDials: 2
5859
})
5960
const dialerReleaseTokenSpy = sinon.spy(dialer, 'releaseToken')
@@ -98,7 +99,7 @@ describe('Dial Request', () => {
9899
const dialAction: DialAction = async (num) => await actions[num.toString()]()
99100
const addrs = Object.keys(actions)
100101
const controller = new AbortController()
101-
const dialer = new Dialer({
102+
const dialer = new DefaultDialer(new Components(), {
102103
maxParallelDials: 2
103104
})
104105
const dialerReleaseTokenSpy = sinon.spy(dialer, 'releaseToken')
@@ -138,7 +139,7 @@ describe('Dial Request', () => {
138139

139140
const dialAction: DialAction = async (num) => await actions[num.toString()]()
140141
const controller = new AbortController()
141-
const dialer = new Dialer({
142+
const dialer = new DefaultDialer(new Components(), {
142143
maxParallelDials: 2
143144
})
144145
const dialerReleaseTokenSpy = sinon.spy(dialer, 'releaseToken')
@@ -184,7 +185,7 @@ describe('Dial Request', () => {
184185
const dialAction: DialAction = async (num) => await actions[num.toString()]()
185186
const addrs = Object.keys(actions)
186187
const controller = new AbortController()
187-
const dialer = new Dialer({
188+
const dialer = new DefaultDialer(new Components(), {
188189
maxParallelDials: 2
189190
})
190191
const dialerReleaseTokenSpy = sinon.spy(dialer, 'releaseToken')
@@ -237,7 +238,7 @@ describe('Dial Request', () => {
237238

238239
const dialRequest = new DialRequest({
239240
addrs: Object.keys(actions).map(str => new Multiaddr(str)),
240-
dialer: new Dialer({
241+
dialer: new DefaultDialer(new Components(), {
241242
maxParallelDials: 3
242243
}),
243244
dialAction: async (ma, opts) => {

test/dialing/direct.node.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { Connection, isConnection } from '@libp2p/interface-connection'
1717
import { AbortError } from '@libp2p/interfaces/errors'
1818
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
1919
import { MemoryDatastore } from 'datastore-core/memory'
20-
import { Dialer } from '../../src/connection-manager/dialer/index.js'
20+
import { DefaultDialer } from '../../src/connection-manager/dialer/index.js'
2121
import { DefaultAddressManager } from '../../src/address-manager/index.js'
2222
import { PersistentPeerStore } from '@libp2p/peer-store'
2323
import { DefaultTransportManager } from '../../src/transport-manager.js'
@@ -95,26 +95,23 @@ describe('Dialing (direct, TCP)', () => {
9595
})
9696

9797
it('should be able to connect to a remote node via its multiaddr', async () => {
98-
const dialer = new Dialer()
99-
dialer.init(localComponents)
98+
const dialer = new DefaultDialer(localComponents)
10099

101100
const connection = await dialer.dial(remoteAddr)
102101
expect(connection).to.exist()
103102
await connection.close()
104103
})
105104

106105
it('should fail to connect to an unsupported multiaddr', async () => {
107-
const dialer = new Dialer()
108-
dialer.init(localComponents)
106+
const dialer = new DefaultDialer(localComponents)
109107

110108
await expect(dialer.dial(unsupportedAddr))
111109
.to.eventually.be.rejectedWith(Error)
112110
.and.to.have.nested.property('.code', ErrorCodes.ERR_NO_VALID_ADDRESSES)
113111
})
114112

115113
it('should fail to connect if peer has no known addresses', async () => {
116-
const dialer = new Dialer()
117-
dialer.init(localComponents)
114+
const dialer = new DefaultDialer(localComponents)
118115
const peerId = await createFromJSON(Peers[1])
119116

120117
await expect(dialer.dial(peerId))
@@ -125,8 +122,7 @@ describe('Dialing (direct, TCP)', () => {
125122
it('should be able to connect to a given peer id', async () => {
126123
await localComponents.getPeerStore().addressBook.set(remoteComponents.getPeerId(), remoteTM.getAddrs())
127124

128-
const dialer = new Dialer()
129-
dialer.init(localComponents)
125+
const dialer = new DefaultDialer(localComponents)
130126

131127
const connection = await dialer.dial(remoteComponents.getPeerId())
132128
expect(connection).to.exist()
@@ -136,8 +132,7 @@ describe('Dialing (direct, TCP)', () => {
136132
it('should fail to connect to a given peer with unsupported addresses', async () => {
137133
await localComponents.getPeerStore().addressBook.add(remoteComponents.getPeerId(), [unsupportedAddr])
138134

139-
const dialer = new Dialer()
140-
dialer.init(localComponents)
135+
const dialer = new DefaultDialer(localComponents)
141136

142137
await expect(dialer.dial(remoteComponents.getPeerId()))
143138
.to.eventually.be.rejectedWith(Error)
@@ -150,8 +145,7 @@ describe('Dialing (direct, TCP)', () => {
150145
const peerId = await createFromJSON(Peers[1])
151146
await localComponents.getPeerStore().addressBook.add(peerId, [...remoteAddrs, unsupportedAddr])
152147

153-
const dialer = new Dialer()
154-
dialer.init(localComponents)
148+
const dialer = new DefaultDialer(localComponents)
155149

156150
sinon.spy(localTM, 'dial')
157151
const connection = await dialer.dial(peerId)
@@ -162,10 +156,9 @@ describe('Dialing (direct, TCP)', () => {
162156
})
163157

164158
it('should abort dials on queue task timeout', async () => {
165-
const dialer = new Dialer({
159+
const dialer = new DefaultDialer(localComponents, {
166160
dialTimeout: 50
167161
})
168-
dialer.init(localComponents)
169162

170163
sinon.stub(localTM, 'dial').callsFake(async (addr, options = {}) => {
171164
expect(options.signal).to.exist()
@@ -191,10 +184,9 @@ describe('Dialing (direct, TCP)', () => {
191184

192185
await localComponents.getPeerStore().addressBook.add(peerId, addrs)
193186

194-
const dialer = new Dialer({
187+
const dialer = new DefaultDialer(localComponents, {
195188
maxParallelDials: 2
196189
})
197-
dialer.init(localComponents)
198190

199191
expect(dialer.tokens).to.have.lengthOf(2)
200192

0 commit comments

Comments
 (0)