in src/rpc.cc [2327:2405]
void findPeersImpl(Deferrer& defer) {
std::vector<std::string_view> nameList;
std::vector<PeerImpl*> peerList;
{
std::lock_guard l(findPeerMutex_);
if (findPeerList_.empty()) {
return;
}
std::swap(nameList, findPeerLocalNameList_);
std::swap(nameList, findPeerList_);
std::swap(peerList, findPeerLocalPeerList_);
findPeerList_.clear();
peerList.clear();
}
size_t n = 0;
{
std::lock_guard l(peersMutex_);
n = peers_.size();
}
peerList.reserve(n + n / 4);
{
std::lock_guard l(peersMutex_);
for (auto& v : peers_) {
peerList.push_back(&v.second);
}
}
auto now = std::chrono::steady_clock::now();
peerList.erase(
std::remove_if(
peerList.begin(), peerList.end(),
[&](PeerImpl* p) {
if (!p->hasId.load(std::memory_order_relaxed)) {
return true;
}
for (auto& v : p->connections_) {
if (p->isConnected(v)) {
return false;
}
}
if (now - p->lastFindPeers <= std::chrono::seconds(2)) {
return false;
}
return true;
}),
peerList.end());
log("findPeers has %d/%d peers with live connection\n", peerList.size(), n);
bool anySuccess = false;
if (!peerList.empty()) {
size_t nToKeep = std::min((size_t)std::ceil(std::log2(n)), peerList.size());
nToKeep = std::max(nToKeep, std::min(n, (size_t)2));
while (peerList.size() > nToKeep) {
std::swap(peerList.back(), peerList.at(random<size_t>(0, peerList.size() - 1)));
peerList.pop_back();
}
log("looking among %d peers\n", peerList.size());
BufferHandle buffer;
serializeToBuffer(buffer, (uint32_t)1, (uint32_t)Rpc::reqLookingForPeer, nameList);
SharedBufferHandle shared{buffer.release()};
for (auto* p : peerList) {
p->lastFindPeers = now;
anySuccess |= p->banditSend(
connectionEnabledMask.load(std::memory_order_relaxed), shared, defer, nullptr, nullptr, false);
}
}
if (anySuccess) {
std::lock_guard l(findPeerMutex_);
std::swap(nameList, findPeerLocalNameList_);
std::swap(peerList, findPeerLocalPeerList_);
} else {
// log("No connectivity to any peers for search; keeping find list\n");
std::lock_guard l(findPeerMutex_);
std::swap(nameList, findPeerList_);
std::swap(peerList, findPeerLocalPeerList_);
}
}