@@ -16,6 +16,32 @@ export function selectRandomPeer(peers: Peer[]): Peer | undefined {
16
16
return peers [ index ] ;
17
17
}
18
18
19
+ /**
20
+ * Returns the peer with the lowest latency.
21
+ * @param getPing - A function that returns the latency for a given peer
22
+ * @param peers - The list of peers to choose from
23
+ * @returns The peer with the lowest latency, or undefined if no peer could be reached
24
+ */
25
+ export async function selectLowestLatencyPeer (
26
+ peerPings : Map < string , number > ,
27
+ peers : Peer [ ]
28
+ ) : Promise < Peer | undefined > {
29
+ if ( peers . length === 0 ) return ;
30
+
31
+ const results = await Promise . all (
32
+ peers . map ( ( peer ) => {
33
+ const ping = peerPings . get ( peer . id . toString ( ) ) ?? Infinity ;
34
+ return { peer, ping } ;
35
+ } )
36
+ ) ;
37
+
38
+ const lowestLatencyResult = results . sort ( ( a , b ) => a . ping - b . ping ) [ 0 ] ;
39
+
40
+ return lowestLatencyResult . ping !== Infinity
41
+ ? lowestLatencyResult . peer
42
+ : undefined ;
43
+ }
44
+
19
45
/**
20
46
* Returns the list of peers that supports the given protocol.
21
47
*/
@@ -35,12 +61,19 @@ export async function getPeersForProtocol(
35
61
return peers ;
36
62
}
37
63
64
+ /**
65
+ * Returns a peer that supports the given protocol.
66
+ * If peerId is provided, the peer with that id is returned.
67
+ * Otherwise, the peer with the lowest latency is returned.
68
+ * If no peer is found from the above criteria, a random peer is returned.
69
+ */
38
70
export async function selectPeerForProtocol (
39
71
peerStore : PeerStore ,
72
+ peerPings : Map < string , number > ,
40
73
protocols : string [ ] ,
41
74
peerId ?: PeerId
42
75
) : Promise < { peer : Peer ; protocol : string } > {
43
- let peer ;
76
+ let peer : Peer | undefined ;
44
77
if ( peerId ) {
45
78
peer = await peerStore . get ( peerId ) ;
46
79
if ( ! peer ) {
@@ -50,11 +83,13 @@ export async function selectPeerForProtocol(
50
83
}
51
84
} else {
52
85
const peers = await getPeersForProtocol ( peerStore , protocols ) ;
53
- peer = selectRandomPeer ( peers ) ;
86
+ peer = await selectLowestLatencyPeer ( peerPings , peers ) ;
54
87
if ( ! peer ) {
55
- throw new Error (
56
- `Failed to find known peer that registers protocols: ${ protocols } `
57
- ) ;
88
+ peer = selectRandomPeer ( peers ) ;
89
+ if ( ! peer )
90
+ throw new Error (
91
+ `Failed to find known peer that registers protocols: ${ protocols } `
92
+ ) ;
58
93
}
59
94
}
60
95
0 commit comments