MCPcopy Create free account
hub / github.com/Achain-Dev/Achain / fetch_items_loop

Method fetch_items_loop

src/Chain/libraries/net/Node.cpp:1093–1210  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1091 }
1092
1093 void NodeImpl::fetch_items_loop()
1094 {
1095 VERIFY_CORRECT_THREAD();
1096 while (!_fetch_item_loop_done.canceled())
1097 {
1098 _items_to_fetch_updated = false;
1099 dlog("beginning an iteration of fetch items (${count} items to fetch)",
1100 ("count", _items_to_fetch.size()));
1101
1102 fc::time_point oldest_timestamp_to_fetch = fc::time_point::now() - fc::seconds(10 * 5);
1103 fc::time_point next_peer_unblocked_time = fc::time_point::maximum();
1104
1105 // we need to construct a list of items to request from each peer first,
1106 // then send the messages (in two steps, to avoid yielding while iterating)
1107 // we want to evenly distribute our requests among our peers.
1108 struct requested_item_count_index {};
1109 struct peer_and_items_to_fetch
1110 {
1111 PeerConnectionPtr peer;
1112 std::vector<ItemId> item_ids;
1113 peer_and_items_to_fetch(const PeerConnectionPtr& peer) : peer(peer) {}
1114 bool operator<(const peer_and_items_to_fetch& rhs) const { return peer < rhs.peer; }
1115 size_t number_of_items() const { return item_ids.size(); }
1116 };
1117 typedef boost::multi_index_container<peer_and_items_to_fetch,
1118 boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::member<peer_and_items_to_fetch, PeerConnectionPtr, &peer_and_items_to_fetch::peer> >,
1119 boost::multi_index::ordered_non_unique<boost::multi_index::tag<requested_item_count_index>,
1120 boost::multi_index::const_mem_fun<peer_and_items_to_fetch, size_t, &peer_and_items_to_fetch::number_of_items> > > > fetch_messages_to_send_set;
1121 fetch_messages_to_send_set items_by_peer;
1122
1123 // initialize the fetch_messages_to_send with an empty set of items for all idle peers
1124 for (const PeerConnectionPtr& peer : _active_connections)
1125 if (peer->idle())
1126 items_by_peer.insert(peer_and_items_to_fetch(peer));
1127
1128 // now loop over all items we want to fetch
1129 for (auto item_iter = _items_to_fetch.begin(); item_iter != _items_to_fetch.end();)
1130 {
1131 if (item_iter->time_stamp < oldest_timestamp_to_fetch)
1132 {
1133 // this item has probably already fallen out of our peers' caches, we'll just ignore it.
1134 // this can happen during flooding, and the _items_to_fetch could otherwise get clogged
1135 // with a bunch of items that we'll never be able to request from any peer
1136 wlog("Unable to fetch item ${item} before its likely expiration time, removing it from our list of items to fetch", ("item", item_iter->item));
1137 item_iter = _items_to_fetch.erase(item_iter);
1138 }
1139 else
1140 {
1141 // find a peer that has it, we'll use the one who has the least requests going to it to load balance
1142 bool item_fetched = false;
1143 for (auto peer_iter = items_by_peer.get<requested_item_count_index>().begin(); peer_iter != items_by_peer.get<requested_item_count_index>().end(); ++peer_iter)
1144 {
1145 const PeerConnectionPtr& peer = peer_iter->peer;
1146 // if they have the item and we haven't already decided to ask them for too many other items
1147 if (peer_iter->item_ids.size() < ALP_NET_MAX_ITEMS_PER_PEER_DURING_NORMAL_OPERATION &&
1148 peer->inventory_peer_advertised_to_us.find(item_iter->item) != peer->inventory_peer_advertised_to_us.end())
1149 {
1150 if (item_iter->item.item_type == thinkyoung::net::trx_message_type && peer->is_transaction_fetching_inhibited())

Callers

nothing calls this directly

Calls 15

nowFunction · 0.85
FetchItemsMessageClass · 0.85
ptrFunction · 0.85
idleMethod · 0.80
get_remote_endpointMethod · 0.80
secondsFunction · 0.50
maximumClass · 0.50
minClass · 0.50
value_typeEnum · 0.50
microsecondsClass · 0.50

Tested by

no test coverage detected