js-libp2p
js-libp2p copied to clipboard
fix: subsequent dial abort
This PR propagates the AbortController signal to already in progress dials.
When a nodes attempts to dial another node, libp2p checks if there is an in progress dial before adding the dial request to the queue of dials. If there is a dial in progress, the new dial will reuse the same promise already being resolved.
There is one scenario where unexpected behaviours might occur, which this PR aims to solve. Considering the next flow:
libp2p.dial(peerId)
libp2p.dial(peerId, { signal })
The second dial will leverage the previous dial (already in progress), but the abort signal would not be triggable. While this flow would not be common, under the hood it might be. If libp2p has autoDial enabled (which is the default!), once new peer addresses are added to the AddressBook, the peer will be dialed (if connMgr upper bound not reached).
The autoDial will trigger a libp2p.dial(peerId), but then a user might perform in the application level a libp2p.dial(peerId, { signal }) at the same time. If the user tries to use the signal, it will simply not work.
--
In this PR, the timeout signal is leveraged to abort a dial, if subsequent abort signals are called. The ideal solution would be to add new signals on the fly and combine them (as done in the initial dial https://github.com/libp2p/js-libp2p/blob/v0.29.0/src/dialer/index.js#L162 ). However, the transports are already listening for abort on the previous reference and it would need to be replaces, which would mean considerable changes in the transports to support this.