@@ -23,7 +23,7 @@ interface ToConnectionOptions {
23
23
* https://github.com/libp2p/interface-transport#multiaddrconnection
24
24
*/
25
25
export const toMultiaddrConnection = ( socket : Socket , options : ToConnectionOptions ) : MultiaddrConnection => {
26
- let status : 'open' | 'closing' | 'closed' = 'open'
26
+ let closePromise : Promise < void > | null = null
27
27
const log = options . logger . forComponent ( 'libp2p:tcp:socket' )
28
28
const metrics = options . metrics
29
29
const metricPrefix = options . metricPrefix ?? ''
@@ -127,11 +127,15 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
127
127
timeline : { open : Date . now ( ) } ,
128
128
129
129
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 )
132
132
return
133
133
}
134
- status = 'closing'
134
+
135
+ if ( closePromise != null ) {
136
+ log ( 'The %s socket is closed or closing' , lOptsStr )
137
+ return closePromise
138
+ }
135
139
136
140
if ( options . signal == null ) {
137
141
const signal = AbortSignal . timeout ( closeTimeout )
@@ -150,12 +154,11 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
150
154
151
155
try {
152
156
log ( '%s closing socket' , lOptsStr )
153
- await new Promise < void > ( ( resolve , reject ) => {
157
+ closePromise = new Promise < void > ( ( resolve , reject ) => {
154
158
socket . once ( 'close' , ( ) => {
155
159
// socket completely closed
156
160
log ( '%s socket closed' , lOptsStr )
157
161
158
- status = 'closed'
159
162
resolve ( )
160
163
} )
161
164
socket . once ( 'error' , ( err : Error ) => {
@@ -165,9 +168,10 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
165
168
if ( maConn . timeline . close == null ) {
166
169
maConn . timeline . close = Date . now ( )
167
170
}
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
171
175
} )
172
176
173
177
// shorten inactivity timeout
@@ -189,6 +193,8 @@ export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptio
189
193
socket . destroy ( )
190
194
}
191
195
} )
196
+
197
+ await closePromise
192
198
} catch ( err : any ) {
193
199
this . abort ( err )
194
200
} finally {
0 commit comments