Skip to content

Commit 5b004c0

Browse files
authored
fix: do not re-register metrics (#3153)
If the server is paused and resumed, the `listening` event handler is invoked again. Move metric registration out of the handler so it is not repeated.
1 parent 8efb065 commit 5b004c0

File tree

2 files changed

+67
-72
lines changed

2 files changed

+67
-72
lines changed

packages/transport-tcp/src/index.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,25 @@
2828
*/
2929

3030
import { TCP } from './tcp.js'
31-
import type { CloseServerOnMaxConnectionsOpts } from './listener.js'
3231
import type { ComponentLogger, CounterGroup, Metrics, CreateListenerOptions, DialTransportOptions, Transport, OutboundConnectionUpgradeEvents } from '@libp2p/interface'
3332
import type { ProgressEvent } from 'progress-events'
3433

35-
export type { CloseServerOnMaxConnectionsOpts }
34+
export interface CloseServerOnMaxConnectionsOpts {
35+
/**
36+
* Server listens once connection count is less than `listenBelow`
37+
*/
38+
listenBelow: number
39+
40+
/**
41+
* Close server once connection count is greater than or equal to `closeAbove`
42+
*/
43+
closeAbove: number
44+
45+
/**
46+
* Invoked when there was an error listening on a socket
47+
*/
48+
onListenError?(err: Error): void
49+
}
3650

3751
export interface TCPOptions {
3852
/**

packages/transport-tcp/src/listener.ts

Lines changed: 51 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,11 @@ import { multiaddr } from '@multiformats/multiaddr'
55
import { pEvent } from 'p-event'
66
import { toMultiaddrConnection } from './socket-to-conn.js'
77
import { multiaddrToNetConfig } from './utils.js'
8-
import type { TCPCreateListenerOptions } from './index.js'
8+
import type { CloseServerOnMaxConnectionsOpts, TCPCreateListenerOptions } from './index.js'
99
import type { NetConfig } from './utils.js'
1010
import type { ComponentLogger, Logger, MultiaddrConnection, CounterGroup, MetricGroup, Metrics, Listener, ListenerEvents, Upgrader } from '@libp2p/interface'
1111
import type { Multiaddr } from '@multiformats/multiaddr'
1212

13-
export interface CloseServerOnMaxConnectionsOpts {
14-
/**
15-
* Server listens once connection count is less than `listenBelow`
16-
*/
17-
listenBelow: number
18-
19-
/**
20-
* Close server once connection count is greater than or equal to `closeAbove`
21-
*/
22-
closeAbove: number
23-
24-
/**
25-
* Invoked when there was an error listening on a socket
26-
*/
27-
onListenError?(err: Error): void
28-
}
29-
3013
interface Context extends TCPCreateListenerOptions {
3114
upgrader: Upgrader
3215
socketInactivityTimeout?: number
@@ -38,10 +21,10 @@ interface Context extends TCPCreateListenerOptions {
3821
logger: ComponentLogger
3922
}
4023

41-
export interface TCPListenerMetrics {
42-
status: MetricGroup
43-
errors: CounterGroup
44-
events: CounterGroup
24+
interface TCPListenerMetrics {
25+
status?: MetricGroup
26+
errors?: CounterGroup
27+
events?: CounterGroup
4528
}
4629

4730
enum TCPListenerStatusCode {
@@ -67,7 +50,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
6750
/** Keep track of open sockets to destroy in case of timeout */
6851
private readonly sockets = new Set<net.Socket>()
6952
private status: Status = { code: TCPListenerStatusCode.INACTIVE }
70-
private metrics?: TCPListenerMetrics
53+
private metrics: TCPListenerMetrics
7154
private addr: string
7255
private readonly log: Logger
7356
private readonly shutdownController: AbortController
@@ -100,59 +83,57 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
10083
}
10184
}
10285

103-
this.server
104-
.on('listening', () => {
105-
if (context.metrics != null) {
106-
// we are listening, register metrics for our port
107-
const address = this.server.address()
108-
109-
if (address == null) {
110-
this.addr = 'unknown'
111-
} else if (typeof address === 'string') {
112-
// unix socket
113-
this.addr = address
114-
} else {
115-
this.addr = `${address.address}:${address.port}`
116-
}
86+
context.metrics?.registerMetricGroup('libp2p_tcp_inbound_connections_total', {
87+
label: 'address',
88+
help: 'Current active connections in TCP listener',
89+
calculate: () => {
90+
return {
91+
[this.addr]: this.sockets.size
92+
}
93+
}
94+
})
11795

118-
context.metrics?.registerMetricGroup('libp2p_tcp_inbound_connections_total', {
119-
label: 'address',
120-
help: 'Current active connections in TCP listener',
121-
calculate: () => {
122-
return {
123-
[this.addr]: this.sockets.size
124-
}
125-
}
126-
})
127-
128-
this.metrics = {
129-
status: context.metrics.registerMetricGroup('libp2p_tcp_listener_status_info', {
130-
label: 'address',
131-
help: 'Current status of the TCP listener socket'
132-
}),
133-
errors: context.metrics.registerMetricGroup('libp2p_tcp_listener_errors_total', {
134-
label: 'address',
135-
help: 'Total count of TCP listener errors by type'
136-
}),
137-
events: context.metrics.registerMetricGroup('libp2p_tcp_listener_events_total', {
138-
label: 'address',
139-
help: 'Total count of TCP listener events by type'
140-
})
141-
}
96+
this.metrics = {
97+
status: context.metrics?.registerMetricGroup('libp2p_tcp_listener_status_info', {
98+
label: 'address',
99+
help: 'Current status of the TCP listener socket'
100+
}),
101+
errors: context.metrics?.registerMetricGroup('libp2p_tcp_listener_errors_total', {
102+
label: 'address',
103+
help: 'Total count of TCP listener errors by type'
104+
}),
105+
events: context.metrics?.registerMetricGroup('libp2p_tcp_listener_events_total', {
106+
label: 'address',
107+
help: 'Total count of TCP listener events by type'
108+
})
109+
}
142110

143-
this.metrics?.status.update({
144-
[this.addr]: TCPListenerStatusCode.ACTIVE
145-
})
111+
this.server
112+
.on('listening', () => {
113+
// we are listening, register metrics for our port
114+
const address = this.server.address()
115+
116+
if (address == null) {
117+
this.addr = 'unknown'
118+
} else if (typeof address === 'string') {
119+
// unix socket
120+
this.addr = address
121+
} else {
122+
this.addr = `${address.address}:${address.port}`
146123
}
147124

125+
this.metrics.status?.update({
126+
[this.addr]: TCPListenerStatusCode.ACTIVE
127+
})
128+
148129
this.safeDispatchEvent('listening')
149130
})
150131
.on('error', err => {
151-
this.metrics?.errors.increment({ [`${this.addr} listen_error`]: true })
132+
this.metrics.errors?.increment({ [`${this.addr} listen_error`]: true })
152133
this.safeDispatchEvent('error', { detail: err })
153134
})
154135
.on('close', () => {
155-
this.metrics?.status.update({
136+
this.metrics.status?.update({
156137
[this.addr]: this.status.code
157138
})
158139

@@ -165,12 +146,12 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
165146
}
166147
})
167148
.on('drop', () => {
168-
this.metrics?.events.increment({ [`${this.addr} drop`]: true })
149+
this.metrics.events?.increment({ [`${this.addr} drop`]: true })
169150
})
170151
}
171152

172153
private onSocket (socket: net.Socket): void {
173-
this.metrics?.events.increment({ [`${this.addr} connection`]: true })
154+
this.metrics.events?.increment({ [`${this.addr} connection`]: true })
174155

175156
if (this.status.code !== TCPListenerStatusCode.ACTIVE) {
176157
socket.destroy()
@@ -190,7 +171,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
190171
})
191172
} catch (err: any) {
192173
this.log.error('inbound connection failed', err)
193-
this.metrics?.errors.increment({ [`${this.addr} inbound_to_connection`]: true })
174+
this.metrics.errors?.increment({ [`${this.addr} inbound_to_connection`]: true })
194175
socket.destroy()
195176
return
196177
}
@@ -233,7 +214,7 @@ export class TCPListener extends TypedEventEmitter<ListenerEvents> implements Li
233214
})
234215
.catch(async err => {
235216
this.log.error('inbound connection upgrade failed', err)
236-
this.metrics?.errors.increment({ [`${this.addr} inbound_upgrade`]: true })
217+
this.metrics.errors?.increment({ [`${this.addr} inbound_upgrade`]: true })
237218
this.sockets.delete(socket)
238219
maConn.abort(err)
239220
})

0 commit comments

Comments
 (0)