Skip to content

Commit

Permalink
Merge pull request ddnet#9479 from Robyt3/Storage-Error-Handling
Browse files Browse the repository at this point in the history
Improve storage initialization and error handling, refactoring
  • Loading branch information
def- authored Jan 4, 2025
2 parents 16fb284 + 62c9ed4 commit 43524b9
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 171 deletions.
35 changes: 35 additions & 0 deletions src/base/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,38 @@ void CFutureLogger::OnFilterChange()
pLogger->SetFilter(m_Filter);
}
}

void CMemoryLogger::Log(const CLogMessage *pMessage)
{
if(m_pParentLogger)
{
m_pParentLogger->Log(pMessage);
}
if(m_Filter.Filters(pMessage))
{
return;
}
const CLockScope LockScope(m_MessagesMutex);
m_vMessages.push_back(*pMessage);
}

std::vector<CLogMessage> CMemoryLogger::Lines()
{
const CLockScope LockScope(m_MessagesMutex);
return m_vMessages;
}

std::string CMemoryLogger::ConcatenatedLines()
{
const CLockScope LockScope(m_MessagesMutex);
std::string Result;
for(const CLogMessage &Message : m_vMessages)
{
if(!Result.empty())
{
Result += '\n';
}
Result += Message.m_aLine;
}
return Result;
}
25 changes: 25 additions & 0 deletions src/base/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <atomic>
#include <memory>
#include <string>
#include <vector>

typedef void *IOHANDLE;
Expand Down Expand Up @@ -247,6 +248,30 @@ class CFutureLogger : public ILogger
void OnFilterChange() override;
};

/**
* @ingroup Log
*
* Logger that collects messages in memory. This is useful to collect the log
* messages for a particular operation and show them in a user interface when
* the operation failed. Use only temporarily with @link CLogScope @endlink
* or it will result in excessive memory usage.
*
* Messages are also forwarded to the parent logger if it's set, regardless
* of this logger's filter.
*/
class CMemoryLogger : public ILogger
{
ILogger *m_pParentLogger = nullptr;
std::vector<CLogMessage> m_vMessages GUARDED_BY(m_MessagesMutex);
CLock m_MessagesMutex;

public:
void SetParent(ILogger *pParentLogger) { m_pParentLogger = pParentLogger; }
void Log(const CLogMessage *pMessage) override REQUIRES(!m_MessagesMutex);
std::vector<CLogMessage> Lines() REQUIRES(!m_MessagesMutex);
std::string ConcatenatedLines() REQUIRES(!m_MessagesMutex);
};

/**
* @ingroup Log
*
Expand Down
21 changes: 18 additions & 3 deletions src/engine/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4067,8 +4067,7 @@ void CClient::Con_BenchmarkQuit(IConsole::IResult *pResult, void *pUserData)

void CClient::BenchmarkQuit(int Seconds, const char *pFilename)
{
char aBuf[IO_MAX_PATH_LENGTH];
m_BenchmarkFile = Storage()->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_ABSOLUTE, aBuf, sizeof(aBuf));
m_BenchmarkFile = Storage()->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_ABSOLUTE);
m_BenchmarkStopTime = time_get() + time_freq() * Seconds;
}

Expand Down Expand Up @@ -4708,7 +4707,23 @@ int main(int argc, const char **argv)
delete pEngine;
});

IStorage *pStorage = CreateStorage(IStorage::STORAGETYPE_CLIENT, argc, argv);
IStorage *pStorage;
{
CMemoryLogger MemoryLogger;
MemoryLogger.SetParent(log_get_scope_logger());
{
CLogScope LogScope(&MemoryLogger);
pStorage = CreateStorage(IStorage::EInitializationType::CLIENT, argc, argv);
}
if(!pStorage)
{
log_error("client", "Failed to initialize the storage location (see details above)");
std::string Message = "Failed to initialize the storage location. See details below.\n\n" + MemoryLogger.ConcatenatedLines();
pClient->ShowMessageBox("Storage Error", Message.c_str());
PerformAllCleanup();
return -1;
}
}
pKernel->RegisterInterface(pStorage);

pFutureAssertionLogger->Set(CreateAssertionLogger(pStorage, GAME_NAME));
Expand Down
7 changes: 6 additions & 1 deletion src/engine/server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ int main(int argc, const char **argv)
IEngine *pEngine = CreateEngine(GAME_NAME, pFutureConsoleLogger, 2 * std::thread::hardware_concurrency() + 2);
pKernel->RegisterInterface(pEngine);

IStorage *pStorage = CreateStorage(IStorage::STORAGETYPE_SERVER, argc, argv);
IStorage *pStorage = CreateStorage(IStorage::EInitializationType::SERVER, argc, argv);
if(!pStorage)
{
log_error("server", "failed to initialize storage");
return -1;
}
pKernel->RegisterInterface(pStorage);

pFutureAssertionLogger->Set(CreateAssertionLogger(pStorage, GAME_NAME));
Expand Down
Loading

0 comments on commit 43524b9

Please sign in to comment.