I wrote a network logger which works in separate thread. The idea was to allow application push any amount of data and logger should process it separately without slowing down the main thread. The pseudocode looks like:
void LogCoroutine::runLogic()
{
mBackgroundWorker = std::thread(&LogCoroutine::logic, this);
mBackgroundWorker.detach();
}
void LogCoroutine::logic()
{
while (true)
{
_serverLogic();
_senderLogic();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 10ms
}
}
void LogCoroutine::_senderLogic()
{
std::lock_guard<std::mutex> lock(mMutex);
while (!mMessages.empty() && !mClients.empty())
{
std::string nextMessage = mMessages.front();
mMessages.pop_front();
_sendMessage(nextMessage);
}
}
_serverLogic
checks the socket for the new connections (peers) and _senderLogic
processes queue with messages and send it to all connected peers.
And the last function: pushing message:
void LogCoroutine::pushMessage(const std::string& message)
{
std::lock_guard<std::mutex> lock(mMutex);
mMessages.push_back(message);
}
Everything works well when the packages send not very often. There is a cycle when application starts which logs a lot of information. And application hangs up for a 5-10 seconds, without logging it doesn't slow down.
So, where is the bottleneck of this architecture? Maybe pushing each message with mutex inside is a bad idea?