re annouce with exponential back-off
This commit is contained in:
parent
bc5599a230
commit
74414d0999
@ -67,6 +67,9 @@ add_library(solanaceae_sha1_ngcft1
|
|||||||
./solanaceae/ngc_ft1_sha1/participation.hpp
|
./solanaceae/ngc_ft1_sha1/participation.hpp
|
||||||
./solanaceae/ngc_ft1_sha1/participation.cpp
|
./solanaceae/ngc_ft1_sha1/participation.cpp
|
||||||
|
|
||||||
|
./solanaceae/ngc_ft1_sha1/re_announce_systems.hpp
|
||||||
|
./solanaceae/ngc_ft1_sha1/re_announce_systems.cpp
|
||||||
|
|
||||||
./solanaceae/ngc_ft1_sha1/chunk_picker_systems.hpp
|
./solanaceae/ngc_ft1_sha1/chunk_picker_systems.hpp
|
||||||
./solanaceae/ngc_ft1_sha1/chunk_picker_systems.cpp
|
./solanaceae/ngc_ft1_sha1/chunk_picker_systems.cpp
|
||||||
|
|
||||||
|
@ -25,6 +25,25 @@ bool FT1ChunkSHA1Cache::haveChunk(const SHA1Digest& hash) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReAnnounceTimer::set(const float new_timer) {
|
||||||
|
timer = new_timer;
|
||||||
|
last_max = new_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReAnnounceTimer::reset(void) {
|
||||||
|
if (last_max <= 0.01f) {
|
||||||
|
last_max = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_max *= 2.f;
|
||||||
|
timer = last_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReAnnounceTimer::lower(void) {
|
||||||
|
timer *= 0.1f;
|
||||||
|
last_max *= 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
void TransferStatsTally::Peer::trimSent(const float time_now) {
|
void TransferStatsTally::Peer::trimSent(const float time_now) {
|
||||||
while (recently_sent.size() > 4 && time_now - recently_sent.front().time_point > 1.f) {
|
while (recently_sent.size() > 4 && time_now - recently_sent.front().time_point > 1.f) {
|
||||||
recently_sent.pop_front();
|
recently_sent.pop_front();
|
||||||
|
@ -75,6 +75,23 @@ namespace Components {
|
|||||||
float timer {0.f};
|
float timer {0.f};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AnnounceTargets {
|
||||||
|
entt::dense_set<Contact3> targets;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ReAnnounceTimer {
|
||||||
|
float timer {0.f};
|
||||||
|
float last_max {0.f};
|
||||||
|
|
||||||
|
void set(const float new_timer);
|
||||||
|
|
||||||
|
// exponential back-off
|
||||||
|
void reset(void);
|
||||||
|
|
||||||
|
// on peer join to group
|
||||||
|
void lower(void);
|
||||||
|
};
|
||||||
|
|
||||||
struct DownloadPriority {
|
struct DownloadPriority {
|
||||||
// download/retreival priority in comparison to other objects
|
// download/retreival priority in comparison to other objects
|
||||||
// not all backends implement this
|
// not all backends implement this
|
||||||
|
83
solanaceae/ngc_ft1_sha1/re_announce_systems.cpp
Normal file
83
solanaceae/ngc_ft1_sha1/re_announce_systems.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "./re_announce_systems.hpp"
|
||||||
|
|
||||||
|
#include "./components.hpp"
|
||||||
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
#include <solanaceae/tox_contacts/components.hpp>
|
||||||
|
#include <solanaceae/ngc_ft1/ngcft1_file_kind.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace Systems {
|
||||||
|
|
||||||
|
void re_announce(
|
||||||
|
ObjectRegistry& os_reg,
|
||||||
|
Contact3Registry& cr,
|
||||||
|
NGCEXTEventProvider& neep,
|
||||||
|
const float delta
|
||||||
|
) {
|
||||||
|
std::vector<Object> to_remove;
|
||||||
|
os_reg.view<Components::ReAnnounceTimer>().each([&os_reg, &cr, &neep, &to_remove, delta](Object ov, Components::ReAnnounceTimer& rat) {
|
||||||
|
ObjectHandle o{os_reg, ov};
|
||||||
|
// if paused -> remove
|
||||||
|
if (o.all_of<Message::Components::Transfer::TagPaused>()) {
|
||||||
|
to_remove.push_back(ov);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not downloading or info incomplete -> remove
|
||||||
|
if (!o.all_of<Components::FT1ChunkSHA1Cache, Components::FT1InfoSHA1Hash, Components::AnnounceTargets>()) {
|
||||||
|
to_remove.push_back(ov);
|
||||||
|
assert(false && "transfer in broken state");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.get<Components::FT1ChunkSHA1Cache>().have_all) {
|
||||||
|
// transfer done, we stop announcing
|
||||||
|
to_remove.push_back(ov);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// update all timers
|
||||||
|
rat.timer -= delta;
|
||||||
|
|
||||||
|
// send announces
|
||||||
|
if (rat.timer <= 0.f) {
|
||||||
|
rat.reset(); // exponential back-off
|
||||||
|
|
||||||
|
std::vector<uint8_t> announce_id;
|
||||||
|
const uint32_t file_kind = static_cast<uint32_t>(NGCFT1_file_kind::HASH_SHA1_INFO);
|
||||||
|
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
||||||
|
announce_id.push_back((file_kind>>(i*8)) & 0xff);
|
||||||
|
}
|
||||||
|
assert(o.all_of<Components::FT1InfoSHA1Hash>());
|
||||||
|
const auto& info_hash = o.get<Components::FT1InfoSHA1Hash>().hash;
|
||||||
|
announce_id.insert(announce_id.cend(), info_hash.cbegin(), info_hash.cend());
|
||||||
|
|
||||||
|
for (const auto cv : o.get<Components::AnnounceTargets>().targets) {
|
||||||
|
if (cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(cv)) {
|
||||||
|
// private ?
|
||||||
|
const auto [group_number, peer_number] = cr.get<Contact::Components::ToxGroupPeerEphemeral>(cv);
|
||||||
|
neep.send_pc1_announce(group_number, peer_number, announce_id.data(), announce_id.size());
|
||||||
|
} else if (cr.all_of<Contact::Components::ToxGroupEphemeral>(cv)) {
|
||||||
|
// public
|
||||||
|
const auto group_number = cr.get<Contact::Components::ToxGroupEphemeral>(cv).group_number;
|
||||||
|
neep.send_all_pc1_announce(group_number, announce_id.data(), announce_id.size());
|
||||||
|
} else {
|
||||||
|
assert(false && "we dont know how to announce to this target");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto ov : to_remove) {
|
||||||
|
os_reg.remove<Components::ReAnnounceTimer>(ov);
|
||||||
|
// we keep the annouce target list around (if it exists)
|
||||||
|
// TODO: should we make the target list more generic?
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: how to handle unpause?
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Systems
|
||||||
|
|
17
solanaceae/ngc_ft1_sha1/re_announce_systems.hpp
Normal file
17
solanaceae/ngc_ft1_sha1/re_announce_systems.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/object_store/object_store.hpp>
|
||||||
|
#include <solanaceae/contact/contact_model3.hpp>
|
||||||
|
#include <solanaceae/ngc_ext/ngcext.hpp>
|
||||||
|
|
||||||
|
namespace Systems {
|
||||||
|
|
||||||
|
void re_announce(
|
||||||
|
ObjectRegistry& os_reg,
|
||||||
|
Contact3Registry& cr,
|
||||||
|
NGCEXTEventProvider& neep,
|
||||||
|
const float delta
|
||||||
|
);
|
||||||
|
|
||||||
|
} // Systems
|
||||||
|
|
@ -23,6 +23,7 @@
|
|||||||
#include "./chunk_picker.hpp"
|
#include "./chunk_picker.hpp"
|
||||||
#include "./participation.hpp"
|
#include "./participation.hpp"
|
||||||
|
|
||||||
|
#include "./re_announce_systems.hpp"
|
||||||
#include "./chunk_picker_systems.hpp"
|
#include "./chunk_picker_systems.hpp"
|
||||||
#include "./transfer_stats_systems.hpp"
|
#include "./transfer_stats_systems.hpp"
|
||||||
|
|
||||||
@ -289,6 +290,8 @@ float SHA1_NGCFT1::iterate(float delta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Systems::re_announce(_os.registry(), _cr, _neep, delta);
|
||||||
|
|
||||||
{ // send out bitsets
|
{ // send out bitsets
|
||||||
// currently 1 per tick
|
// currently 1 per tick
|
||||||
if (!_queue_send_bitset.empty()) {
|
if (!_queue_send_bitset.empty()) {
|
||||||
@ -531,33 +534,21 @@ bool SHA1_NGCFT1::onEvent(const Message::Events::MessageUpdated& e) {
|
|||||||
|
|
||||||
ce.emplace<Message::Components::Transfer::File>(std::move(file_impl));
|
ce.emplace<Message::Components::Transfer::File>(std::move(file_impl));
|
||||||
|
|
||||||
// announce we are participating
|
// queue announce we are participating
|
||||||
// since this is the first time, we publicly announce to all
|
// since this is the first time, we publicly announce to all
|
||||||
if (e.e.all_of<Message::Components::ContactFrom, Message::Components::ContactTo>()) {
|
if (e.e.all_of<Message::Components::ContactFrom, Message::Components::ContactTo>()) {
|
||||||
const auto c_f = e.e.get<Message::Components::ContactFrom>().c;
|
const auto c_f = e.e.get<Message::Components::ContactFrom>().c;
|
||||||
const auto c_t = e.e.get<Message::Components::ContactTo>().c;
|
const auto c_t = e.e.get<Message::Components::ContactTo>().c;
|
||||||
|
|
||||||
std::vector<uint8_t> announce_id;
|
|
||||||
const uint32_t file_kind = static_cast<uint32_t>(NGCFT1_file_kind::HASH_SHA1_INFO);
|
|
||||||
for (size_t i = 0; i < sizeof(file_kind); i++) {
|
|
||||||
announce_id.push_back((file_kind>>(i*8)) & 0xff);
|
|
||||||
}
|
|
||||||
assert(ce.all_of<Components::FT1InfoSHA1Hash>());
|
|
||||||
const auto& info_hash = ce.get<Components::FT1InfoSHA1Hash>().hash;
|
|
||||||
announce_id.insert(announce_id.cend(), info_hash.cbegin(), info_hash.cend());
|
|
||||||
|
|
||||||
if (_cr.all_of<Contact::Components::ToxGroupEphemeral>(c_t)) {
|
if (_cr.all_of<Contact::Components::ToxGroupEphemeral>(c_t)) {
|
||||||
// public
|
// public
|
||||||
const auto group_number = _cr.get<Contact::Components::ToxGroupEphemeral>(c_t).group_number;
|
ce.get_or_emplace<Components::AnnounceTargets>().targets.emplace(c_t);
|
||||||
|
|
||||||
_neep.send_all_pc1_announce(group_number, announce_id.data(), announce_id.size());
|
|
||||||
} else if (_cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c_f)) {
|
} else if (_cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(c_f)) {
|
||||||
// private ?
|
// private ?
|
||||||
const auto [group_number, peer_number] = _cr.get<Contact::Components::ToxGroupPeerEphemeral>(c_f);
|
ce.get_or_emplace<Components::AnnounceTargets>().targets.emplace(c_f);
|
||||||
|
|
||||||
_neep.send_pc1_announce(group_number, peer_number, announce_id.data(), announce_id.size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ce.get_or_emplace<Components::ReAnnounceTimer>(0.1f, 60.f*(_rng()%5120) / 1024.f).timer = (_rng()%512) / 1024.f;
|
||||||
|
|
||||||
ce.remove<Message::Components::Transfer::TagPaused>();
|
ce.remove<Message::Components::Transfer::TagPaused>();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user