Prevent head of line blocking and track server resource download progress

This commit is contained in:
Yousef Khadadeh 2025-10-10 10:34:12 +03:00
parent 344ef4093a
commit 2aab3e9e60
14 changed files with 179 additions and 83 deletions

View file

@ -20,8 +20,7 @@ class ClientData {
uint64_t canvasScale = 0;
std::queue<ResourceData> pendingResourceData;
std::queue<ServerClientID> pendingResourceID;
ServerClientID pendingResourceID = {0, 0};
template <typename Archive> void serialize(Archive& a) {
a(camCoords, windowSize, cursorPos, cursorColor, displayName);

View file

@ -13,8 +13,8 @@ enum ServerCommands : MessageCommandType {
SERVER_ERASE_SINGLE_COMPONENT,
SERVER_ERASE_MANY_COMPONENTS,
SERVER_UPDATE_COMPONENT,
SERVER_RESOURCE_INIT,
SERVER_RESOURCE_DATA,
SERVER_NEW_RESOURCE_ID,
SERVER_NEW_RESOURCE_DATA,
SERVER_CHAT_MESSAGE,
SERVER_NEW_BOOKMARK,
SERVER_REMOVE_BOOKMARK,

View file

@ -185,33 +185,22 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID):
comp->server_send_update(*this, isFinalUpdate);
}
});
netServer->add_recv_callback(SERVER_RESOURCE_INIT, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
netServer->add_recv_callback(SERVER_NEW_RESOURCE_ID, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
auto& c = clients[client->customID];
ServerClientID newID;
message(newID);
if(c.pendingResourceData.empty())
c.pendingResourceID.emplace(newID);
else {
netServer->send_items_to_all_clients_except(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_ID, newID);
netServer->send_items_to_all_clients_except(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_DATA, c.pendingResourceData.front());
data.resources.emplace(newID, c.pendingResourceData.front());
c.pendingResourceData.pop();
}
message(c.pendingResourceID);
if(c.pendingResourceID == ServerClientID{0, 0})
throw std::runtime_error("[MainServer::MainServer] Received a null resource ID");
});
netServer->add_recv_callback(SERVER_RESOURCE_DATA, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
netServer->add_recv_callback(SERVER_NEW_RESOURCE_DATA, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
ResourceData resourceData;
message(resourceData);
auto& c = clients[client->customID];
if(c.pendingResourceID.empty()) {
c.pendingResourceData.emplace();
c.pendingResourceData.back() = std::move(resourceData);
}
else {
netServer->send_items_to_all_clients_except(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_ID, c.pendingResourceID.front());
netServer->send_items_to_all_clients_except(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_DATA, resourceData);
data.resources.emplace(c.pendingResourceID.front(), resourceData);
c.pendingResourceID.pop();
}
if(c.pendingResourceID == ServerClientID{0, 0})
throw std::runtime_error("[MainServer::MainServer] Received data for a null resource ID");
netServer->send_items_to_all_clients_except(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_ID, c.pendingResourceID);
netServer->send_items_to_all_clients_except(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_DATA, resourceData);
data.resources.emplace(c.pendingResourceID, resourceData);
c.pendingResourceID = ServerClientID{0, 0};
});
netServer->add_recv_callback(SERVER_CHAT_MESSAGE, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
std::string chatMessage;
@ -326,6 +315,28 @@ void MainServer::update() {
}
}
std::unordered_map<ServerClientID, NetLibrary::DownloadProgress> MainServer::resource_download_progress() {
std::unordered_map<ServerClientID, NetLibrary::DownloadProgress> toRet;
if(!netServer)
return toRet;
for(auto& [serverID, c] : clients) {
if(c.pendingResourceID != ServerClientID{0, 0}) {
const std::vector<std::shared_ptr<NetServer::ClientData>>& clientListInNetServer = netServer->get_client_list();
auto netClientIt = std::find_if(clientListInNetServer.begin(), clientListInNetServer.end(), [&serverID](auto& nC) {
return nC->customID == serverID;
});
if(netClientIt != clientListInNetServer.end()) {
auto& netClient = *netClientIt;
toRet.emplace(c.pendingResourceID, netClient->get_progress_into_fragmented_message(RESOURCE_COMMAND_CHANNEL));
}
}
}
return toRet;
}
MainServer::~MainServer() {
//netServer->close_server();
}

View file

@ -12,6 +12,7 @@ class MainServer {
~MainServer();
std::shared_ptr<NetServer> netServer;
std::unordered_map<ServerPortionID, ClientData> clients;
std::unordered_map<ServerClientID, NetLibrary::DownloadProgress> resource_download_progress();
private:
World& world;
void ensure_display_name_unique(std::string& displayName);