Don't overload the network with many requests while fetching the server list

This commit is contained in:
smallmodel 2025-04-27 21:58:35 +02:00
parent cd272d24c9
commit f03cdeb745
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512

View file

@ -31,7 +31,7 @@ Fax(714)549-0757
* 3.3) The server list sends the list request to connected masters, and receives the data for each. * 3.3) The server list sends the list request to connected masters, and receives the data for each.
* 3.4) When finished fetching 1 master (got `\final`), the server list state transitions to `sl_querying`. * 3.4) When finished fetching 1 master (got `\final`), the server list state transitions to `sl_querying`.
* 3.5) The server list queries all fetched servers. It can still continue fetching list from currently connected masters * 3.5) The server list queries all fetched servers. It can still continue fetching list from currently connected masters
* but it will not connect to other masters while servers are being queried. * but it will not connect to other masters while servers are being queried. It won't be sending more queries if remaining masters replied in under 500 ms.
* 3.6) When finished querying all fetched servers, the server list restarts from 3.2 and queries next masters. * 3.6) When finished querying all fetched servers, the server list restarts from 3.2 and queries next masters.
* *
* The idea here is to ensure the redundancy of the server list between multiple masters even if the results are combined. * The idea here is to ensure the redundancy of the server list between multiple masters even if the results are combined.
@ -79,6 +79,7 @@ extern int ServerListGetMsPort(int index);
//#define MSPORT ServerListGetMsPort(0) //#define MSPORT ServerListGetMsPort(0)
#define SERVER_GROWBY 64 #define SERVER_GROWBY 64
#define LAN_SEARCH_TIME 3000 //3 sec #define LAN_SEARCH_TIME 3000 //3 sec
#define SERVER_QUERY_MAX_PAUSE 500
#define INTERNET_SEARCH_TIME 10000 //10 sec #define INTERNET_SEARCH_TIME 10000 //10 sec
#define LIST_NUMKEYBUCKETS 500 #define LIST_NUMKEYBUCKETS 500
#define LIST_NUMKEYCHAINS 4 #define LIST_NUMKEYCHAINS 4
@ -129,6 +130,7 @@ struct GServerListImplementation
GServerListSocket slsockets; GServerListSocket slsockets;
int numslsockets; int numslsockets;
int startslindex; int startslindex;
gsi_time lastsltime;
unsigned long lanstarttime; unsigned long lanstarttime;
GQueryType querytype; GQueryType querytype;
HashTable keylist; HashTable keylist;
@ -155,7 +157,7 @@ const int querylengths[NUM_QUERYTYPES] = {7,6,7,9,13,8};
static void KeyValFree(void *elem); static void KeyValFree(void *elem);
static int KeyValCompareKeyA(const void *entry1, const void *entry2); static int KeyValCompareKeyA(const void *entry1, const void *entry2);
static int KeyValHashKeyA(const void *elem, int numbuckets); static int KeyValHashKeyA(const void *elem, int numbuckets);
static gbool ServerListHasFinishedFetchingList(GServerList serverlist);
/* ServerListNew /* ServerListNew
---------------- ----------------
@ -189,12 +191,14 @@ GServerList ServerListNew(const char *gamename, const char *enginename, const ch
list->numslsockets = maxconcupdates / 4; list->numslsockets = maxconcupdates / 4;
if (list->numslsockets < 1) { if (list->numslsockets < 1) {
list->numslsockets = 1; list->numslsockets = 1;
} else if (list->numslsockets > 2) { } else if (list->numslsockets > 4) {
list->numslsockets = 2; // Above 4 seems too much
list->numslsockets = 4;
} }
list->slsockets = (GServerListSocket)malloc(sizeof(struct GServerListSocketImplementation) * list->numslsockets); list->slsockets = (GServerListSocket)malloc(sizeof(struct GServerListSocketImplementation) * list->numslsockets);
memset(list->slsockets, 0, sizeof(struct GServerListSocketImplementation) * list->numslsockets); memset(list->slsockets, 0, sizeof(struct GServerListSocketImplementation) * list->numslsockets);
list->startslindex = 0; list->startslindex = 0;
list->lastsltime = current_time();
SocketStartUp(); SocketStartUp();
return list; return list;
@ -909,6 +913,9 @@ static GError ServerListReadList(GServerList serverlist, GServerListSocket slsoc
} }
slsocket->lastreplytime = current_time();
serverlist->lastsltime = slsocket->lastreplytime;
if (serverlist->encryptdata && slsocket->cryptinfo.offset != -1) { if (serverlist->encryptdata && slsocket->cryptinfo.offset != -1) {
// Added in 2.0 // Added in 2.0
crypt_docrypt(&slsocket->cryptinfo, slsocket->data + slsocket->oldlen, len); crypt_docrypt(&slsocket->cryptinfo, slsocket->data + slsocket->oldlen, len);
@ -977,7 +984,6 @@ static GError ServerListReadList(GServerList serverlist, GServerListSocket slsoc
} }
slsocket->oldlen = slsocket->oldlen - (p - slsocket->data); slsocket->oldlen = slsocket->oldlen - (p - slsocket->data);
memmove(slsocket->data,p,slsocket->oldlen); //shift it over memmove(slsocket->data,p,slsocket->oldlen); //shift it over
slsocket->lastreplytime = current_time();
return 0; return 0;
} }
@ -1061,7 +1067,7 @@ static GError ServerListQueryLoop(GServerList serverlist)
return 0; return 0;
} }
if (serverlist->startslindex < ServerListGetNumMasters() || !ServerListFinishedList(serverlist)) { if (serverlist->startslindex < ServerListGetNumMasters() || !ServerListHasFinishedFetchingList(serverlist)) {
ServerListModeChange(serverlist, sl_listxfer); ServerListModeChange(serverlist, sl_listxfer);
} else { } else {
// No more masters // No more masters
@ -1069,7 +1075,13 @@ static GError ServerListQueryLoop(GServerList serverlist)
} }
return 0; return 0;
} }
if (!ServerListHasFinishedFetchingList(serverlist) && current_time() < serverlist->lastsltime + SERVER_QUERY_MAX_PAUSE) {
// Make sure to not send out other queries if currently fetching from other lists
// to avoid overloading the network
return GE_BUSY;
}
//now, send out queries on available sockets //now, send out queries on available sockets
for (i = 0 ; i < serverlist->maxupdates && serverlist->nextupdate < ArrayLength(serverlist->servers) ; i++) for (i = 0 ; i < serverlist->maxupdates && serverlist->nextupdate < ArrayLength(serverlist->servers) ; i++)
if (serverlist->updatelist[i].currentserver == NULL) //it's availalbe if (serverlist->updatelist[i].currentserver == NULL) //it's availalbe
@ -1132,10 +1144,10 @@ GError ServerListThinkSocket(GServerList serverlist, GServerListSocket slsocket)
return 0; return 0;
} }
/* ServerListFinishedList /* ServerListHasFinishedFetchingList
------------------ ------------------
Whether or not the list has finished fetching */ Whether or not the list has finished fetching */
static gbool ServerListFinishedList(GServerList serverlist) static gbool ServerListHasFinishedFetchingList(GServerList serverlist)
{ {
int i; int i;
@ -1164,8 +1176,12 @@ GError ServerListThink(GServerList serverlist)
{ {
case sl_idle: case sl_idle:
case sl_listxfer: case sl_listxfer:
if (!serverlist->abortupdate && serverlist->startslindex < ServerListGetNumMasters()) { if (!serverlist->abortupdate) {
CreateServerListForAvailableSockets(serverlist, serverlist->async); if (serverlist->startslindex < ServerListGetNumMasters()) {
CreateServerListForAvailableSockets(serverlist, serverlist->async);
} else if (serverlist->state == sl_listxfer && ServerListHasFinishedFetchingList(serverlist)) {
ServerListModeChange(serverlist, sl_idle);
}
} }
break; break;
case sl_querying: case sl_querying: