MCPcopy Create free account
hub / github.com/bitshares/bitshares-core / fetch_items_loop

Method fetch_items_loop

libraries/net/node.cpp:630–757  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

628 }
629
630 void node_impl::fetch_items_loop()
631 {
632 VERIFY_CORRECT_THREAD();
633 while (!_fetch_item_loop_done.canceled())
634 {
635 _items_to_fetch_updated = false;
636 dlog("beginning an iteration of fetch items (${count} items to fetch)",
637 ("count", _items_to_fetch.size()));
638
639 fc::time_point oldest_timestamp_to_fetch = fc::time_point::now()
640 - fc::seconds(_recent_block_interval_seconds * GRAPHENE_NET_MESSAGE_CACHE_DURATION_IN_BLOCKS);
641 fc::time_point next_peer_unblocked_time = fc::time_point::maximum();
642
643 // we need to construct a list of items to request from each peer first,
644 // then send the messages (in two steps, to avoid yielding while iterating)
645 // we want to evenly distribute our requests among our peers.
646 struct requested_item_count_index {};
647 struct peer_and_items_to_fetch
648 {
649 peer_connection_ptr peer;
650 std::vector<item_id> item_ids;
651 peer_and_items_to_fetch(const peer_connection_ptr& peer) : peer(peer) {}
652 bool operator<(const peer_and_items_to_fetch& rhs) const { return peer < rhs.peer; }
653 size_t number_of_items() const { return item_ids.size(); }
654 };
655 using fetch_messages_to_send_set = boost::multi_index_container< peer_and_items_to_fetch, bmi::indexed_by<
656 bmi::ordered_unique<
657 bmi::member<peer_and_items_to_fetch, peer_connection_ptr, &peer_and_items_to_fetch::peer> >,
658 bmi::ordered_non_unique< bmi::tag<requested_item_count_index>,
659 bmi::const_mem_fun<peer_and_items_to_fetch, size_t, &peer_and_items_to_fetch::number_of_items> >
660 > >;
661 fetch_messages_to_send_set items_by_peer;
662
663 // initialize the fetch_messages_to_send with an empty set of items for all idle peers
664 {
665 fc::scoped_lock<fc::mutex> lock(_active_connections.get_mutex());
666 for (const peer_connection_ptr& peer : _active_connections)
667 if (peer->idle())
668 items_by_peer.insert(peer_and_items_to_fetch(peer));
669 }
670
671 // now loop over all items we want to fetch
672 for (auto item_iter = _items_to_fetch.begin(); item_iter != _items_to_fetch.end();)
673 {
674 if (item_iter->timestamp < oldest_timestamp_to_fetch)
675 {
676 // this item has probably already fallen out of our peers' caches, we'll just ignore it.
677 // this can happen during flooding, and the _items_to_fetch could otherwise get clogged
678 // with a bunch of items that we'll never be able to request from any peer
679 wlog("Unable to fetch item ${item} before its likely expiration time, "
680 "removing it from our list of items to fetch",
681 ("item", item_iter->item));
682 item_iter = _items_to_fetch.erase(item_iter);
683 }
684 else
685 {
686 // find a peer that has it, we'll use the one who has the least requests going to it to load balance
687 bool item_fetched = false;

Callers

nothing calls this directly

Calls 15

fetch_items_messageClass · 0.85
idleMethod · 0.80
eraseMethod · 0.80
get_remote_endpointMethod · 0.80
waitMethod · 0.80
sizeMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
findMethod · 0.45
modifyMethod · 0.45

Tested by

no test coverage detected