diff --git a/solanaceae/ngc_ft1/cca.hpp b/solanaceae/ngc_ft1/cca.hpp index 750e04e..6328c39 100644 --- a/solanaceae/ngc_ft1/cca.hpp +++ b/solanaceae/ngc_ft1/cca.hpp @@ -60,7 +60,7 @@ struct CCAI { // TODO: api for how much data we should send // take time since last sent into account // respect max_byterate_allowed - virtual int64_t canSend(void) = 0; + virtual int64_t canSend(float time_delta) = 0; // get the list of timed out seq_ids virtual std::vector getTimeouts(void) const = 0; diff --git a/solanaceae/ngc_ft1/cubic.cpp b/solanaceae/ngc_ft1/cubic.cpp index 7fdb426..2a930c8 100644 --- a/solanaceae/ngc_ft1/cubic.cpp +++ b/solanaceae/ngc_ft1/cubic.cpp @@ -69,8 +69,8 @@ float CUBIC::getWindow(void) { return std::min(getCWnD(), FlowOnly::getWindow()); } -int64_t CUBIC::canSend(void) { - const auto fspace_pkgs = FlowOnly::canSend(); +int64_t CUBIC::canSend(float time_delta) { + const auto fspace_pkgs = FlowOnly::canSend(time_delta); if (fspace_pkgs == 0u) { return 0u; @@ -86,11 +86,6 @@ int64_t CUBIC::canSend(void) { // this is mostly to prevent spikes on empty windows const auto rate = window / getCurrentDelay(); - // assuming at most 20ms tick interval - // TODO: pass down actual tick interval - //const float time_delta = 0.02f; // 20ms - const float time_delta = 0.01666f; - // we dont want this limit to fall below atleast 1 segment const int64_t max_bytes_per_tick = std::max(rate * time_delta + 0.5f, MAXIMUM_SEGMENT_SIZE); cspace_bytes = std::min(cspace_bytes, max_bytes_per_tick); diff --git a/solanaceae/ngc_ft1/cubic.hpp b/solanaceae/ngc_ft1/cubic.hpp index 9f838d7..85ce099 100644 --- a/solanaceae/ngc_ft1/cubic.hpp +++ b/solanaceae/ngc_ft1/cubic.hpp @@ -38,7 +38,7 @@ struct CUBIC : public FlowOnly { // TODO: api for how much data we should send // take time since last sent into account // respect max_byterate_allowed - int64_t canSend(void) override; + int64_t canSend(float time_delta) override; // get the list of timed out seq_ids //std::vector getTimeouts(void) const override; diff --git a/solanaceae/ngc_ft1/flow_only.cpp b/solanaceae/ngc_ft1/flow_only.cpp index 3f058c0..2a1499c 100644 --- a/solanaceae/ngc_ft1/flow_only.cpp +++ b/solanaceae/ngc_ft1/flow_only.cpp @@ -33,7 +33,7 @@ float FlowOnly::getWindow(void) { return _fwnd; } -int64_t FlowOnly::canSend(void) { +int64_t FlowOnly::canSend(float time_delta) { if (_in_flight.empty()) { assert(_in_flight_bytes == 0); return MAXIMUM_SEGMENT_DATA_SIZE; @@ -48,9 +48,7 @@ int64_t FlowOnly::canSend(void) { // also limit to max sendrate per tick, which is usually smaller than window // this is mostly to prevent spikes on empty windows - // assuming at most 20ms tick interval - // TODO: pass down actual tick interval - fspace = std::min(fspace, max_byterate_allowed * 0.02f + 0.5f); + fspace = std::min(fspace, max_byterate_allowed * time_delta + 0.5f); // limit to whole packets return (fspace / MAXIMUM_SEGMENT_DATA_SIZE) * MAXIMUM_SEGMENT_DATA_SIZE; diff --git a/solanaceae/ngc_ft1/flow_only.hpp b/solanaceae/ngc_ft1/flow_only.hpp index b1aaf71..4c1e624 100644 --- a/solanaceae/ngc_ft1/flow_only.hpp +++ b/solanaceae/ngc_ft1/flow_only.hpp @@ -63,7 +63,7 @@ struct FlowOnly : public CCAI { // TODO: api for how much data we should send // take time since last sent into account // respect max_byterate_allowed - int64_t canSend(void) override; + int64_t canSend(float time_delta) override; // get the list of timed out seq_ids std::vector getTimeouts(void) const override; diff --git a/solanaceae/ngc_ft1/ledbat.cpp b/solanaceae/ngc_ft1/ledbat.cpp index ca5cb41..f4f86b8 100644 --- a/solanaceae/ngc_ft1/ledbat.cpp +++ b/solanaceae/ngc_ft1/ledbat.cpp @@ -20,7 +20,7 @@ LEDBAT::LEDBAT(size_t maximum_segment_data_size) : CCAI(maximum_segment_data_siz _time_start_offset = clock::now(); } -int64_t LEDBAT::canSend(void) { +int64_t LEDBAT::canSend(float time_delta) { if (_in_flight.empty()) { return MAXIMUM_SEGMENT_DATA_SIZE; } diff --git a/solanaceae/ngc_ft1/ledbat.hpp b/solanaceae/ngc_ft1/ledbat.hpp index af836ed..acca247 100644 --- a/solanaceae/ngc_ft1/ledbat.hpp +++ b/solanaceae/ngc_ft1/ledbat.hpp @@ -59,7 +59,7 @@ struct LEDBAT : public CCAI { // TODO: api for how much data we should send // take time since last sent into account // respect max_byterate_allowed - int64_t canSend(void) override; + int64_t canSend(float time_delta) override; // get the list of timed out seq_ids std::vector getTimeouts(void) const override; diff --git a/solanaceae/ngc_ft1/ngcft1.cpp b/solanaceae/ngc_ft1/ngcft1.cpp index 3fbfae6..085e55e 100644 --- a/solanaceae/ngc_ft1/ngcft1.cpp +++ b/solanaceae/ngc_ft1/ngcft1.cpp @@ -298,7 +298,7 @@ void NGCFT1::iteratePeer(float time_delta, uint32_t group_number, uint32_t peer_ auto timeouts = peer.cca->getTimeouts(); std::set timeouts_set{timeouts.cbegin(), timeouts.cend()}; - int64_t can_packet_size {peer.cca->canSend()}; // might get more space while iterating (time) + int64_t can_packet_size {peer.cca->canSend(time_delta)}; // might get more space while iterating (time) // change iterat start position to not starve transfers in the back size_t iterated_count = 0; @@ -335,12 +335,37 @@ NGCFT1::NGCFT1( _tep.subscribe(this, Tox_Event_Type::TOX_EVENT_GROUP_PEER_EXIT); } -void NGCFT1::iterate(float time_delta) { +float NGCFT1::iterate(float time_delta) { + bool transfer_in_progress {false}; for (auto& [group_number, group] : groups) { for (auto& [peer_number, peer] : group.peers) { iteratePeer(time_delta, group_number, peer_number, peer); + + // find any active transfer + if (!transfer_in_progress) { + for (const auto& t : peer.send_transfers) { + if (t.has_value()) { + transfer_in_progress = true; + break; + } + } + } + if (!transfer_in_progress) { + for (const auto& t : peer.recv_transfers) { + if (t.has_value()) { + transfer_in_progress = true; + break; + } + } + } } } + + if (transfer_in_progress) { + return 0.005f; // 5ms + } else { + return 1.f; // once a sec might be too little + } } void NGCFT1::NGC_FT1_send_request_private( diff --git a/solanaceae/ngc_ft1/ngcft1.hpp b/solanaceae/ngc_ft1/ngcft1.hpp index 424c35a..9cfcdb7 100644 --- a/solanaceae/ngc_ft1/ngcft1.hpp +++ b/solanaceae/ngc_ft1/ngcft1.hpp @@ -216,7 +216,7 @@ class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProvider NGCEXTEventProviderI& neep ); - void iterate(float delta); + float iterate(float delta); public: // ft1 api // TODO: public variant?