Skip to content

Commit a6be8f0

Browse files
authored
fix(libp2p): emit peer:discovered event on internal event bus (#2019)
To notifiy components that a new peer has been discovered, emit the `peer:discovered` event on the event bus component. Allows the auto-dialer to choose to dial newly discovered peers immediately instead of waiting for the next autodial interval.
1 parent ac8a1ca commit a6be8f0

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

packages/libp2p/src/connection-manager/auto-dial.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { logger } from '@libp2p/logger'
22
import { PeerMap, PeerSet } from '@libp2p/peer-collections'
33
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
44
import { PeerJobQueue } from '../utils/peer-job-queue.js'
5-
import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_INTERVAL, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PEER_RETRY_THRESHOLD, AUTO_DIAL_PRIORITY, LAST_DIAL_FAILURE_KEY, MIN_CONNECTIONS } from './constants.js'
5+
import { AUTO_DIAL_CONCURRENCY, AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE, AUTO_DIAL_INTERVAL, AUTO_DIAL_MAX_QUEUE_LENGTH, AUTO_DIAL_PEER_RETRY_THRESHOLD, AUTO_DIAL_PRIORITY, LAST_DIAL_FAILURE_KEY, MIN_CONNECTIONS } from './constants.js'
66
import type { Libp2pEvents } from '@libp2p/interface'
77
import type { EventEmitter } from '@libp2p/interface/events'
88
import type { PeerStore } from '@libp2p/interface/peer-store'
@@ -18,6 +18,7 @@ interface AutoDialInit {
1818
autoDialPriority?: number
1919
autoDialInterval?: number
2020
autoDialPeerRetryThreshold?: number
21+
autoDialDiscoveredPeersDebounce?: number
2122
}
2223

2324
interface AutoDialComponents {
@@ -32,7 +33,8 @@ const defaultOptions = {
3233
autoDialConcurrency: AUTO_DIAL_CONCURRENCY,
3334
autoDialPriority: AUTO_DIAL_PRIORITY,
3435
autoDialInterval: AUTO_DIAL_INTERVAL,
35-
autoDialPeerRetryThreshold: AUTO_DIAL_PEER_RETRY_THRESHOLD
36+
autoDialPeerRetryThreshold: AUTO_DIAL_PEER_RETRY_THRESHOLD,
37+
autoDialDiscoveredPeersDebounce: AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE
3638
}
3739

3840
export class AutoDial implements Startable {
@@ -44,6 +46,7 @@ export class AutoDial implements Startable {
4446
private readonly autoDialIntervalMs: number
4547
private readonly autoDialMaxQueueLength: number
4648
private readonly autoDialPeerRetryThresholdMs: number
49+
private readonly autoDialDiscoveredPeersDebounce: number
4750
private autoDialInterval?: ReturnType<typeof setInterval>
4851
private started: boolean
4952
private running: boolean
@@ -61,6 +64,7 @@ export class AutoDial implements Startable {
6164
this.autoDialIntervalMs = init.autoDialInterval ?? defaultOptions.autoDialInterval
6265
this.autoDialMaxQueueLength = init.maxQueueLength ?? defaultOptions.maxQueueLength
6366
this.autoDialPeerRetryThresholdMs = init.autoDialPeerRetryThreshold ?? defaultOptions.autoDialPeerRetryThreshold
67+
this.autoDialDiscoveredPeersDebounce = init.autoDialDiscoveredPeersDebounce ?? defaultOptions.autoDialDiscoveredPeersDebounce
6468
this.started = false
6569
this.running = false
6670
this.queue = new PeerJobQueue({
@@ -77,6 +81,22 @@ export class AutoDial implements Startable {
7781
log.error(err)
7882
})
7983
})
84+
85+
// sometimes peers are discovered in quick succession so add a small
86+
// debounce to ensure all eligible peers are autodialed
87+
let debounce: ReturnType<typeof setTimeout>
88+
89+
// when new peers are discovered, dial them if we don't have
90+
// enough connections
91+
components.events.addEventListener('peer:discovery', () => {
92+
clearTimeout(debounce)
93+
debounce = setTimeout(() => {
94+
this.autoDial()
95+
.catch(err => {
96+
log.error(err)
97+
})
98+
}, this.autoDialDiscoveredPeersDebounce)
99+
})
80100
}
81101

82102
isStarted (): boolean {

packages/libp2p/src/connection-manager/constants.defaults.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export const AUTO_DIAL_MAX_QUEUE_LENGTH = 100
3838
*/
3939
export const AUTO_DIAL_PEER_RETRY_THRESHOLD = 1000 * 60
4040

41+
/**
42+
* @see https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.unknown.ConnectionManagerInit.html#autoDialDiscoveredPeersDebounce
43+
*/
44+
export const AUTO_DIAL_DISCOVERED_PEERS_DEBOUNCE = 10
45+
4146
/**
4247
* @see https://libp2p.github.io/js-libp2p/interfaces/index._internal_.ConnectionManagerConfig.html#inboundConnectionThreshold
4348
*/

packages/libp2p/src/connection-manager/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ export interface ConnectionManagerInit {
7272
*/
7373
autoDialPeerRetryThreshold?: number
7474

75+
/**
76+
* Newly discovered peers may be auto-dialed to increase the number of open
77+
* connections, but they can be discovered in quick succession so add a small
78+
* delay before attempting to dial them in case more peers have been
79+
* discovered. (default: 10ms)
80+
*/
81+
autoDialDiscoveredPeersDebounce?: number
82+
7583
/**
7684
* Sort the known addresses of a peer before trying to dial, By default public
7785
* addresses will be dialled before private (e.g. loopback or LAN) addresses.

packages/libp2p/src/libp2p.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export class Libp2pNode<T extends ServiceMap = Record<string, unknown>> extends
105105
protocols: evt.detail.peer.protocols
106106
}
107107

108-
this.safeDispatchEvent('peer:discovery', { detail: peerInfo })
108+
components.events.safeDispatchEvent('peer:discovery', { detail: peerInfo })
109109
}
110110
})
111111

0 commit comments

Comments
 (0)