diff --git a/CMakeLists.txt b/CMakeLists.txt index 80e5d3e..db0772c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,8 +127,8 @@ add_library(solanaceae_ngchs2 ./solanaceae/ngc_hs2/ngc_hs2_sigma.hpp ./solanaceae/ngc_hs2/ngc_hs2_sigma.cpp - #./solanaceae/ngc_hs2/ngc_hs2_recv.hpp - #./solanaceae/ngc_hs2/ngc_hs2_recv.cpp + ./solanaceae/ngc_hs2/ngc_hs2_rizzler.hpp + ./solanaceae/ngc_hs2/ngc_hs2_rizzler.cpp ) target_include_directories(solanaceae_ngchs2 PUBLIC .) target_compile_features(solanaceae_ngchs2 PUBLIC cxx_std_17) diff --git a/solanaceae/ngc_hs2/ngc_hs2_rizzler.cpp b/solanaceae/ngc_hs2/ngc_hs2_rizzler.cpp new file mode 100644 index 0000000..e2918a9 --- /dev/null +++ b/solanaceae/ngc_hs2/ngc_hs2_rizzler.cpp @@ -0,0 +1,123 @@ +#include "./ngc_hs2_rizzler.hpp" + +#include + +#include + +#include + +#include + +NGCHS2Rizzler::NGCHS2Rizzler( + Contact3Registry& cr, + RegistryMessageModelI& rmm, + ToxContactModel2& tcm, + NGCFT1& nft +) : + _cr(cr), + _rmm(rmm), + _tcm(tcm), + _nft(nft), + _nftep_sr(_nft.newSubRef(this)) +{ + _nftep_sr + .subscribe(NGCFT1_Event::recv_init) + .subscribe(NGCFT1_Event::recv_data) + .subscribe(NGCFT1_Event::recv_done) + ; +} + +NGCHS2Rizzler::~NGCHS2Rizzler(void) { +} + +float NGCHS2Rizzler::iterate(float delta) { + for (auto it = _request_queue.begin(); it != _request_queue.end();) { + it->second.timer += delta; + + if (it->second.timer < it->second.delay) { + it++; + continue; + } + + if (!_cr.all_of(it->first)) { + // peer nolonger online + it = _request_queue.erase(it); + continue; + } + + const auto [group_number, peer_number] = _cr.get(it->first); + + // now in sec + const uint64_t ts_now = Message::getTimeMS()/1000; + + if (sendRequest(group_number, peer_number, ts_now, ts_now-(60*48))) { + // TODO: requeue + // TODO: segment + // TODO: dont request already received ranges + + //// on success, requeue with longer delay (minutes) + + //it->second.timer = 0.f; + //it->second.delay = _delay_next_request_min + _rng_dist(_rng)*_delay_next_request_add; + + //// double the delay for overlap (9m-15m) + //// TODO: finetune + //it->second.sync_delta = uint8_t((it->second.delay/60.f)*2.f) + 1; + + //std::cout << "ZOX #### requeued request in " << it->second.delay << "s\n"; + + it++; + } else { + // on failure, assume disconnected + it = _request_queue.erase(it); + } + + // just choose something small, since we expect a response might arrive soon + //min_interval = std::min(min_interval, _delay_between_syncs_min); + } + + + return 1000.f; +} + +bool NGCHS2Rizzler::sendRequest( + uint32_t group_number, uint32_t peer_number, + uint64_t ts_start, uint64_t ts_end +) { + std::cout << "NGCHS2Rizzler: sending request to " << group_number << ":" << peer_number << " (" << ts_start << "," << ts_end << ")\n"; + return false; +} + +bool NGCHS2Rizzler::onEvent(const Events::NGCFT1_recv_init&) { + return false; +} + +bool NGCHS2Rizzler::onEvent(const Events::NGCFT1_recv_data&) { + return false; +} + +bool NGCHS2Rizzler::onEvent(const Events::NGCFT1_recv_done&) { + return false; +} + +bool NGCHS2Rizzler::onToxEvent(const Tox_Event_Group_Peer_Join* e) { + const auto group_number = tox_event_group_peer_join_get_group_number(e); + const auto peer_number = tox_event_group_peer_join_get_peer_id(e); + + const auto c = _tcm.getContactGroupPeer(group_number, peer_number); + + if (!c) { + return false; + } + + if (!_request_queue.count(c)) { + _request_queue[c] = { + _delay_before_first_request_min + _rng_dist(_rng)*_delay_before_first_request_add, + 0.f, + 0, + }; + } + + return false; +} + diff --git a/solanaceae/ngc_hs2/ngc_hs2_rizzler.hpp b/solanaceae/ngc_hs2/ngc_hs2_rizzler.hpp new file mode 100644 index 0000000..1e8c424 --- /dev/null +++ b/solanaceae/ngc_hs2/ngc_hs2_rizzler.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include + +#include + +// fwd +class ToxContactModel2; +class RegistryMessageModelI; + +class NGCHS2Rizzler : public ToxEventI, public NGCFT1EventI { + Contact3Registry& _cr; + RegistryMessageModelI& _rmm; + ToxContactModel2& _tcm; + NGCFT1& _nft; + NGCFT1EventProviderI::SubscriptionReference _nftep_sr; + + // 5s-6s + const float _delay_before_first_request_min {5.f}; + const float _delay_before_first_request_add {1.f}; + + std::uniform_real_distribution _rng_dist {0.0f, 1.0f}; + std::minstd_rand _rng; + + struct RequestQueueInfo { + float delay; // const + float timer; + uint64_t sync_delta; //? + }; + // request queue + // c -> delay, timer + std::map _request_queue; + + public: + NGCHS2Rizzler( + Contact3Registry& cr, + RegistryMessageModelI& rmm, + ToxContactModel2& tcm, + NGCFT1& nf + ); + + ~NGCHS2Rizzler(void); + + float iterate(float delta); + + protected: + bool sendRequest( + uint32_t group_number, uint32_t peer_number, + uint64_t ts_start, uint64_t ts_end + ); + + protected: + bool onEvent(const Events::NGCFT1_recv_init&) override; + bool onEvent(const Events::NGCFT1_recv_data&) override; + bool onEvent(const Events::NGCFT1_recv_done&) override; + + protected: + bool onToxEvent(const Tox_Event_Group_Peer_Join* e) override; +}; +