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: use same promise when closing maconn multiple times #2487

Merged
merged 2 commits into from
Apr 16, 2024
Merged
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
24 changes: 15 additions & 9 deletions packages/transport-tcp/src/socket-to-conn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* https://github.com/libp2p/interface-transport#multiaddrconnection
*/
export const toMultiaddrConnection = (socket: Socket, options: ToConnectionOptions): MultiaddrConnection => {
let status: 'open' | 'closing' | 'closed' = 'open'
let closePromise: Promise<void> | null = null
const log = options.logger.forComponent('libp2p:tcp:socket')
const metrics = options.metrics
const metricPrefix = options.metricPrefix ?? ''
Expand Down Expand Up @@ -127,11 +127,15 @@
timeline: { open: Date.now() },

async close (options: AbortOptions = {}) {
if (status === 'closed' || status === 'closing' || socket.destroyed) {
log('The %s socket is either closed, closing, or already destroyed', lOptsStr)
if (socket.destroyed) {
log('The %s socket is destroyed', lOptsStr)
return
}
status = 'closing'

if (closePromise != null) {
log('The %s socket is closed or closing', lOptsStr)
return closePromise
}

if (options.signal == null) {
const signal = AbortSignal.timeout(closeTimeout)
Expand All @@ -150,12 +154,11 @@

try {
log('%s closing socket', lOptsStr)
await new Promise<void>((resolve, reject) => {
closePromise = new Promise<void>((resolve, reject) => {
socket.once('close', () => {
// socket completely closed
log('%s socket closed', lOptsStr)

status = 'closed'
resolve()
})
socket.once('error', (err: Error) => {
Expand All @@ -165,9 +168,10 @@
if (maConn.timeline.close == null) {
maConn.timeline.close = Date.now()
}

status = 'closed'
reject(err)
if (!socket.destroyed) {
reject(err)
}

Check warning on line 173 in packages/transport-tcp/src/socket-to-conn.ts

View check run for this annotation

Codecov / codecov/patch

packages/transport-tcp/src/socket-to-conn.ts#L172-L173

Added lines #L172 - L173 were not covered by tests
// if socket is destroyed, 'closed' event will be emitted later to resolve the promise
})

// shorten inactivity timeout
Expand All @@ -189,6 +193,8 @@
socket.destroy()
}
})

await closePromise
} catch (err: any) {
this.abort(err)
} finally {
Expand Down
Loading