From bea57042829f5240580ade7aaa053c74d29d7f19 Mon Sep 17 00:00:00 2001 From: study-faraphel Date: Fri, 8 Nov 2024 00:14:39 +0100 Subject: [PATCH] improved StatList behavior --- CMakeLists.txt | 3 -- Dockerfile | 12 ++++++++ source/Context.hpp | 6 ++-- source/EventManager.cpp | 7 +++-- source/events/info/InfoEvent.cpp | 21 ++++++++++---- source/events/search/SearchEvent.cpp | 4 ++- source/tasks/undefined/UndefinedTask.cpp | 33 ++++++++++++++++------ source/utils/CacheMap.cpp | 1 - source/utils/StatList.cpp | 36 ------------------------ source/utils/StatList.hpp | 30 -------------------- 10 files changed, 63 insertions(+), 90 deletions(-) create mode 100644 Dockerfile delete mode 100644 source/utils/CacheMap.cpp delete mode 100644 source/utils/StatList.cpp delete mode 100644 source/utils/StatList.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c3352b..dcbf533 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,6 @@ add_executable(M2-PT-DRP source/events/types.hpp source/packets/base/GenericPacket.cpp source/RemotePeer.hpp - source/utils/StatList.cpp - source/utils/StatList.hpp source/events/base/BaseEvent.hpp source/events/base/BaseEvent.hpp source/events/audio/AudioPacketsComparator.cpp @@ -46,7 +44,6 @@ add_executable(M2-PT-DRP source/tasks/client/ClientTask.cpp source/tasks/client/ClientTask.hpp source/Context.hpp - source/utils/CacheMap.cpp source/utils/CacheMap.hpp source/packets/search/SearchPacketData.hpp ) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..59c545a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM alpine:latest + +RUN apk add gcc g++ cmake ninja +RUN apk add mpg123-dev openssl-dev portaudio-dev + +WORKDIR /app +COPY . /app + +RUN cmake -S . -B build -G Ninja +RUN cmake --build build + +CMD ["build/M2-PT-DRP"] diff --git a/source/Context.hpp b/source/Context.hpp index 6ac1285..7080848 100644 --- a/source/Context.hpp +++ b/source/Context.hpp @@ -1,18 +1,18 @@ #pragma once #include +#include #include #include "RemotePeer.hpp" -#include "utils/StatList.hpp" struct Context { int socket = -1; addrinfo* broadcastAddressInfo = nullptr; - - drp::util::StatList> remotePeers {}; std::shared_ptr server = nullptr; Peer me; + std::map> remotePeers {}; + std::chrono::high_resolution_clock::time_point latestPeerDiscovery; }; diff --git a/source/EventManager.cpp b/source/EventManager.cpp index c968509..d94165b 100644 --- a/source/EventManager.cpp +++ b/source/EventManager.cpp @@ -56,13 +56,15 @@ EventManager::EventManager() { // get the information for the broadcast local-link address // TODO(Faraphel): ip / port as argument ? if(const int error = getaddrinfo( - "localhost", // TODO: ff02::1 + "0.0.0.0", // TODO: ff02::1 "5650", &addressHints, &context.broadcastAddressInfo ) != 0) throw std::runtime_error("[Sender] Could not get the address: " + std::string(gai_strerror(error))); + // define the time of the latest discovery + this->context.latestPeerDiscovery = std::chrono::high_resolution_clock::now(); } @@ -96,8 +98,9 @@ void EventManager::loopSender() { ) != 0) throw std::runtime_error("[Sender] Could not get the address: " + std::string(gai_strerror(error))); - while (true) { + std::cout << "[Sender] Status: " + std::to_string(static_cast(this->context.me.status)) << std::endl; + // get the corresponding task class std::shared_ptr task; try { diff --git a/source/events/info/InfoEvent.cpp b/source/events/info/InfoEvent.cpp index 9fc107b..8f2922e 100644 --- a/source/events/info/InfoEvent.cpp +++ b/source/events/info/InfoEvent.cpp @@ -13,20 +13,29 @@ void InfoEvent::handle( sockaddr* fromAddress, const socklen_t fromAddressLength ) { - const auto remotePeer = std::make_shared(); + // check if the peer address is already in the map + std::shared_ptr remotePeer; + auto iterator = context.remotePeers.find(*fromAddress); - // TODO(Faraphel): first check if the peer is already in the list - // do not update the time of the list if yes ! + if (iterator == context.remotePeers.end()) { + // if not found, create a new peer + remotePeer = std::make_shared(); + remotePeer->address = *fromAddress; + remotePeer->addressLength = fromAddressLength; + // update the latest discovery time + context.latestPeerDiscovery = std::chrono::high_resolution_clock::now(); + } else { + // get the peer + remotePeer = iterator->second; + } // save the remote peer information - remotePeer->address = *reinterpret_cast(&fromAddress); - remotePeer->addressLength = fromAddressLength; std::memcpy(&remotePeer->information, &content, sizeof(Peer)); // TODO(Faraphel): interpret the timestamp and calculate average ping // save it in the peers list - context.remotePeers.push_back(remotePeer); + context.remotePeers[remotePeer->address] = remotePeer; } diff --git a/source/events/search/SearchEvent.cpp b/source/events/search/SearchEvent.cpp index 97fffdd..1165723 100644 --- a/source/events/search/SearchEvent.cpp +++ b/source/events/search/SearchEvent.cpp @@ -41,8 +41,10 @@ void event::SearchEvent::handle( 0, fromAddress, fromAddressLength - ) == -1) + ) == -1) { std::cerr << "[Receiver] Could not send information: " << strerror(errno) << std::endl; + return; + } std::cout << "[Receiver] Sent information." << std::endl; } diff --git a/source/tasks/undefined/UndefinedTask.cpp b/source/tasks/undefined/UndefinedTask.cpp index d20830e..2cfdda9 100644 --- a/source/tasks/undefined/UndefinedTask.cpp +++ b/source/tasks/undefined/UndefinedTask.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "../../Context.hpp" @@ -23,10 +24,11 @@ void UndefinedTask::handle(Context& context) { // check if no more peers have been found. if ( - std::chrono::high_resolution_clock::now() - context.remotePeers.getModificationTime() > + std::chrono::high_resolution_clock::now() - context.latestPeerDiscovery > std::chrono::milliseconds(5000) ) { // verify if there are peers + // TODO(Faraphel): the map is never empty since there is a least the local client if (context.remotePeers.empty()) { // if we are alone in the network @@ -40,25 +42,38 @@ void UndefinedTask::handle(Context& context) { return; } - // search for a server among the peers - const auto& server = std::find_if( - context.remotePeers.begin(), - context.remotePeers.end(), - [&](const std::shared_ptr& peer) { return peer->status == TaskType::SERVER; } + // look for a server among the peers + const auto& server = std::ranges::find_if( + context.remotePeers, + [&](const auto& peer) { return peer.second->information.status == TaskType::SERVER; } ); + if (server != context.remotePeers.end()) { // if a server have been found, use it - context.server = *server; + context.server = server->second; context.me.status = TaskType::CLIENT; return; } // TODO(Faraphel): check if we have the lowest average ping out of all the peers. If yes, become the server. // Others peers will connect to us on their next loop. + // TODO(Faraphel): use a unique ID instead ? if (!context.me.serverEnabled) return; - ... + // check we have the lowest latency out of all the peers + if (std::all_of( + context.remotePeers.begin(), + context.remotePeers.end(), + [&](const auto& peer) { + return peer.second->information.latencyAverage > context.me.latencyAverage; + } + )) { + // set ourselves as the server + context.server = nullptr; + context.me.status = TaskType::SERVER; + return; + } } // prepare a search message @@ -85,6 +100,8 @@ void UndefinedTask::handle(Context& context) { context.broadcastAddressInfo->ai_addrlen ) == -1) std::cerr << "[Sender] Could not send search event: " << strerror(errno) << std::endl; + + std::this_thread::sleep_for(std::chrono::seconds(1)); } diff --git a/source/utils/CacheMap.cpp b/source/utils/CacheMap.cpp deleted file mode 100644 index c408636..0000000 --- a/source/utils/CacheMap.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "CacheMap.hpp" diff --git a/source/utils/StatList.cpp b/source/utils/StatList.cpp deleted file mode 100644 index 9f0e302..0000000 --- a/source/utils/StatList.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "StatList.hpp" - - -namespace drp::util { - - -template -StatList::StatList() { - this->updateModificationTime(); -} - -template -void StatList::push_back(const T &value) { - std::list::push_back(value); - this->updateModificationTime(); -} - -template -void StatList::pop_back() { - std::list::pop_back(); - this->updateModificationTime(); -} - -template -std::chrono::time_point StatList::getModificationTime() const { - return this->modificationTime; -} - - -template -void StatList::updateModificationTime() { - this->modificationTime = std::chrono::high_resolution_clock::now(); -} - - -} \ No newline at end of file diff --git a/source/utils/StatList.hpp b/source/utils/StatList.hpp deleted file mode 100644 index 43c97da..0000000 --- a/source/utils/StatList.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include - - -namespace drp::util { - - -/** - * A simple list with additional stat data, such as the date of the latest modification - * @tparam Value the type of elements in the list - */ -template -class StatList : public std::list { -public: - StatList(); - - void push_back(const Value& value); - void pop_back(); - - [[nodiscard]] std::chrono::time_point getModificationTime() const; - -private: - void updateModificationTime(); - std::chrono::time_point modificationTime; -}; - - -} \ No newline at end of file