mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge #4586
4586: Fail database queries faster r=def- a=Zwelf Makes ddos situations more bearable during tournaments. Redo of #4429, but this time the tested version. I somehow mixed my two git environments (Laptop and PC) last time and some changes were missing from the PR last time (the initialization of the shutdown variable and m_count variable). Changed the logic a bit from last time to only go into FailMode if the query fails on all database servers. ## Checklist - [x] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test if it works standalone, system.c especially - [ ] Considered possible null pointers and out of bounds array indexing - [x] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: Zwelf <zwelf@strct.cc>
This commit is contained in:
commit
1eac1bbb20
|
@ -9,21 +9,21 @@ class CSemaphore
|
|||
SEMAPHORE m_Sem;
|
||||
// implement the counter seperatly, because the `sem_getvalue`-API is
|
||||
// deprecated on macOS: https://stackoverflow.com/a/16655541
|
||||
std::atomic_int count;
|
||||
std::atomic_int m_Count{0};
|
||||
|
||||
public:
|
||||
CSemaphore() { sphore_init(&m_Sem); }
|
||||
~CSemaphore() { sphore_destroy(&m_Sem); }
|
||||
CSemaphore(const CSemaphore &) = delete;
|
||||
int GetApproximateValue() { return count.load(); }
|
||||
int GetApproximateValue() { return m_Count.load(); }
|
||||
void Wait()
|
||||
{
|
||||
sphore_wait(&m_Sem);
|
||||
count.fetch_sub(1);
|
||||
m_Count.fetch_sub(1);
|
||||
}
|
||||
void Signal()
|
||||
{
|
||||
count.fetch_add(1);
|
||||
m_Count.fetch_add(1);
|
||||
sphore_signal(&m_Sem);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -127,8 +127,15 @@ void CDbConnectionPool::Worker()
|
|||
// remember last working server and try to connect to it first
|
||||
int ReadServer = 0;
|
||||
int WriteServer = 0;
|
||||
// enter fail mode when a sql request fails, skip read request during it and
|
||||
// write to the backup database until all requests are handled
|
||||
bool FailMode = false;
|
||||
while(1)
|
||||
{
|
||||
if(FailMode && m_NumElem.GetApproximateValue() == 0)
|
||||
{
|
||||
FailMode = false;
|
||||
}
|
||||
m_NumElem.Wait();
|
||||
auto pThreadData = std::move(m_aTasks[LastElem++]);
|
||||
// work through all database jobs after OnShutdown is called before exiting the thread
|
||||
|
@ -145,6 +152,16 @@ void CDbConnectionPool::Worker()
|
|||
{
|
||||
for(int i = 0; i < (int)m_aapDbConnections[Mode::READ].size(); i++)
|
||||
{
|
||||
if(m_Shutdown)
|
||||
{
|
||||
dbg_msg("sql", "%s dismissed read request during shutdown", pThreadData->m_pName);
|
||||
break;
|
||||
}
|
||||
if(FailMode)
|
||||
{
|
||||
dbg_msg("sql", "%s dismissed read request during FailMode", pThreadData->m_pName);
|
||||
break;
|
||||
}
|
||||
int CurServer = (ReadServer + i) % (int)m_aapDbConnections[Mode::READ].size();
|
||||
if(ExecSqlFunc(m_aapDbConnections[Mode::READ][CurServer].get(), pThreadData.get(), false))
|
||||
{
|
||||
|
@ -154,12 +171,26 @@ void CDbConnectionPool::Worker()
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(!Success)
|
||||
{
|
||||
FailMode = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CSqlExecData::WRITE_ACCESS:
|
||||
{
|
||||
for(int i = 0; i < (int)m_aapDbConnections[Mode::WRITE].size(); i++)
|
||||
{
|
||||
if(m_Shutdown && !m_aapDbConnections[Mode::WRITE_BACKUP].empty())
|
||||
{
|
||||
dbg_msg("sql", "%s skipped to backup database during shutdown", pThreadData->m_pName);
|
||||
break;
|
||||
}
|
||||
if(FailMode && !m_aapDbConnections[Mode::WRITE_BACKUP].empty())
|
||||
{
|
||||
dbg_msg("sql", "%s skipped to backup database during FailMode", pThreadData->m_pName);
|
||||
break;
|
||||
}
|
||||
int CurServer = (WriteServer + i) % (int)m_aapDbConnections[Mode::WRITE].size();
|
||||
if(ExecSqlFunc(m_aapDbConnections[Mode::WRITE][i].get(), pThreadData.get(), false))
|
||||
{
|
||||
|
@ -171,6 +202,7 @@ void CDbConnectionPool::Worker()
|
|||
}
|
||||
if(!Success)
|
||||
{
|
||||
FailMode = true;
|
||||
for(int i = 0; i < (int)m_aapDbConnections[Mode::WRITE_BACKUP].size(); i++)
|
||||
{
|
||||
if(ExecSqlFunc(m_aapDbConnections[Mode::WRITE_BACKUP][i].get(), pThreadData.get(), true))
|
||||
|
|
|
@ -75,7 +75,7 @@ private:
|
|||
void Worker();
|
||||
bool ExecSqlFunc(IDbConnection *pConnection, struct CSqlExecData *pData, bool Failure);
|
||||
|
||||
std::atomic_bool m_Shutdown;
|
||||
std::atomic_bool m_Shutdown{false};
|
||||
CSemaphore m_NumElem;
|
||||
int FirstElem;
|
||||
int LastElem;
|
||||
|
|
Loading…
Reference in a new issue