void findPeersImpl()

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_);
    }
  }