Skip to content

Commit 160c680

Browse files
update selectPeerForProtocol to return peer with the lowest latency
1 parent f3afd6f commit 160c680

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

packages/utils/src/libp2p/index.ts

+40-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@ export function selectRandomPeer(peers: Peer[]): Peer | undefined {
1616
return peers[index];
1717
}
1818

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+
1945
/**
2046
* Returns the list of peers that supports the given protocol.
2147
*/
@@ -35,12 +61,19 @@ export async function getPeersForProtocol(
3561
return peers;
3662
}
3763

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+
*/
3870
export async function selectPeerForProtocol(
3971
peerStore: PeerStore,
72+
peerPings: Map<string, number>,
4073
protocols: string[],
4174
peerId?: PeerId
4275
): Promise<{ peer: Peer; protocol: string }> {
43-
let peer;
76+
let peer: Peer | undefined;
4477
if (peerId) {
4578
peer = await peerStore.get(peerId);
4679
if (!peer) {
@@ -50,11 +83,13 @@ export async function selectPeerForProtocol(
5083
}
5184
} else {
5285
const peers = await getPeersForProtocol(peerStore, protocols);
53-
peer = selectRandomPeer(peers);
86+
peer = await selectLowestLatencyPeer(peerPings, peers);
5487
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+
);
5893
}
5994
}
6095

0 commit comments

Comments
 (0)