MCPcopy Create free account
hub / github.com/attermann/microReticulum / receive_part

Method receive_part

src/microReticulum/Resource.cpp:834–978  ·  view source on GitHub ↗

Called for each incoming RESOURCE-context packet on the receiver side. Looks the packet up in the in-flight window via its map_hash, files it into parts[], and either kicks off assemble() when all parts have arrived or requests the next window. Mirror Python Resource.py:828. */

Source from the content-addressed store, hash-verified

832requests the next window. Mirror Python Resource.py:828.
833*/
834void Resource::receive_part(const Packet& packet) {
835 TRACE("Resource::receive_part: Received resource part");
836 assert(_object);
837 if (_object->_receive_lock) return;
838 _object->_receive_lock = true;
839
840 _object->_receiving_part = true;
841 _object->_last_activity = Utilities::OS::time();
842 _object->_retries_left = _object->_max_retries;
843
844 if (_object->_req_resp == 0.0) {
845 _object->_req_resp = _object->_last_activity;
846 const double rtt = _object->_req_resp - _object->_req_sent;
847
848 _object->_part_timeout_factor = Type::Resource::PART_TIMEOUT_FACTOR_AFTER_RTT;
849 if (_object->_rtt == 0.0) {
850 _object->_rtt = _object->_link.rtt();
851 watchdog_job();
852 }
853 else if (rtt < _object->_rtt) {
854 _object->_rtt = std::max(_object->_rtt - _object->_rtt * 0.05, rtt);
855 }
856 else if (rtt > _object->_rtt) {
857 _object->_rtt = std::min(_object->_rtt + _object->_rtt * 0.05, rtt);
858 }
859
860 if (rtt > 0) {
861 const double req_resp_cost = static_cast<double>(packet.raw().size() + _object->_req_sent_bytes);
862 _object->_req_resp_rtt_rate = req_resp_cost / rtt;
863
864 if (_object->_req_resp_rtt_rate > Type::Resource::RATE_FAST
865 && _object->_fast_rate_rounds < Type::Resource::FAST_RATE_THRESHOLD) {
866 _object->_fast_rate_rounds++;
867 if (_object->_fast_rate_rounds == Type::Resource::FAST_RATE_THRESHOLD) {
868 _object->_window_max = Type::Resource::WINDOW_MAX_FAST;
869 }
870 }
871 }
872 }
873
874 if (_object->_status == Type::Resource::FAILED) {
875 _object->_receiving_part = false;
876 _object->_receive_lock = false;
877 return;
878 }
879
880 _object->_status = Type::Resource::TRANSFERRING;
881 const Bytes part_data = packet.data();
882 const Bytes part_hash = get_map_hash(part_data);
883
884 const int32_t cci = (_object->_consecutive_completed_height >= 0) ? _object->_consecutive_completed_height : 0;
885 const size_t maphash_len = Type::Resource::MAPHASH_LEN;
886 int32_t i = cci;
887 const size_t window_end = std::min(static_cast<size_t>(cci) + _object->_window,
888 static_cast<size_t>(_object->_total_parts));
889
890 for (size_t j = static_cast<size_t>(cci); j < window_end; ++j) {
891 Bytes map_hash_j = _object->_hashmap.mid(j * maphash_len, maphash_len);

Callers 1

receiveMethod · 0.80

Calls 5

rttMethod · 0.80
dataMethod · 0.80
midMethod · 0.80
PacketClass · 0.70
sizeMethod · 0.45

Tested by

no test coverage detected