Skip to content

Commit ea4f262

Browse files
authored
fix: use same promise when closing maconn multiple times (#2487)
Use same promise when closing`MultiaddrConnection` multiple time See #2478 (review)
1 parent 1c086c9 commit ea4f262

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

packages/transport-tcp/src/socket-to-conn.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ interface ToConnectionOptions {
2323
* https://github.com/libp2p/interface-transport#multiaddrconnection
2424
*/
2525
export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptions): MultiaddrConnection => {
26-
let status: 'open' | 'closing' | 'closed' = 'open'
26+
let closePromise: Promise<void> | null = null
2727
const log = options.logger.forComponent('libp2p:tcp:socket')
2828
const metrics = options.metrics
2929
const metricPrefix = options.metricPrefix ?? ''
@@ -127,11 +127,15 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
127127
timeline: { open: Date.now() },
128128

129129
async close (options: AbortOptions = {}) {
130-
if (status === 'closed' || status === 'closing' || socket.destroyed) {
131-
log('The %s socket is either closed, closing, or already destroyed', lOptsStr)
130+
if (socket.destroyed) {
131+
log('The %s socket is destroyed', lOptsStr)
132132
return
133133
}
134-
status = 'closing'
134+
135+
if (closePromise != null) {
136+
log('The %s socket is closed or closing', lOptsStr)
137+
return closePromise
138+
}
135139

136140
if (options.signal == null) {
137141
const signal = AbortSignal.timeout(closeTimeout)
@@ -150,12 +154,11 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
150154

151155
try {
152156
log('%s closing socket', lOptsStr)
153-
await new Promise<void>((resolve, reject) => {
157+
closePromise = new Promise<void>((resolve, reject) => {
154158
socket.once('close', () => {
155159
// socket completely closed
156160
log('%s socket closed', lOptsStr)
157161

158-
status = 'closed'
159162
resolve()
160163
})
161164
socket.once('error', (err: Error) => {
@@ -165,9 +168,10 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
165168
if (maConn.timeline.close == null) {
166169
maConn.timeline.close = Date.now()
167170
}
168-
169-
status = 'closed'
170-
reject(err)
171+
if (!socket.destroyed) {
172+
reject(err)
173+
}
174+
// if socket is destroyed, 'closed' event will be emitted later to resolve the promise
171175
})
172176

173177
// shorten inactivity timeout
@@ -189,6 +193,8 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
189193
socket.destroy()
190194
}
191195
})
196+
197+
await closePromise
192198
} catch (err: any) {
193199
this.abort(err)
194200
} finally {

0 commit comments

Comments
 (0)