#include "UndefinedTask.hpp" #include "../types.hpp" #include #include #include #include #include #include #include #include #include "../../Context.hpp" #include "../../events/types.hpp" #include "../../packets/base/GenericPacket.hpp" #include "../../packets/search/SearchPacketData.hpp" namespace drp::task { void UndefinedTask::handle(Context& context) { // search if a server is available among the peer. const auto& server = std::ranges::find_if( context.remotePeers, [&](const auto& peer) { return peer.second->information.status == TaskType::SERVER; } ); // if a server have been found, use it if (server != context.remotePeers.end()) { // if a server have been found, use it context.server = server->second; context.me.status = TaskType::CLIENT; return; } // wait that no more new peers are being discovered if ( std::chrono::high_resolution_clock::now() - context.latestPeerDiscovery > std::chrono::milliseconds(5000) ) { // otherwise, become the server if we have the highest ID. // TODO(Faraphel): should use the machine with the lowest average ping if (context.me.serverEnabled) { // find the remote peer with the highest id that can be a server const auto serverCandidate = std::max_element( context.remotePeers.begin(), context.remotePeers.end(), [&](auto& remotePeer1, auto& remotePeer2) { return ( (remotePeer1.second->information.serverEnabled ? remotePeer1.first : 0) < (remotePeer2.second->information.serverEnabled ? remotePeer2.first : 0) ); } ); // check if we are this peer if (context.me.id == serverCandidate->first) { std::cout << "becoming server..." << std::endl; // set ourselves as the server context.server = serverCandidate->second; context.me.status = TaskType::SERVER; return; } } // TODO(Faraphel): sleep 1s } // prepare a search message packet::GenericPacket packet {}; packet::GenericPacketContent packetContent {}; packet::SearchPacketData packetData {}; // broadcast message packet.channel = 0; packet.securityMode = static_cast(packet::SecurityMode::PLAIN); // search message with the time of the message being sent packetContent.eventType = static_cast(event::EventType::SEARCH); packetData.timestamp = std::chrono::high_resolution_clock::now(); std::memcpy(&packetContent.data, &packetData, sizeof(packetData)); packet.setContent(packetContent); // send the search message if (sendto( context.socket, &packet, sizeof(packet), 0, context.broadcastAddressInfo->ai_addr, 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)); } }