void ServerPool::InitConnections() { debug("Initializing connections in ServerPool"); m_iMaxLevel = 0; for (Servers::iterator it = m_Servers.begin(); it != m_Servers.end(); it++) { NewsServer* pNewsServer = *it; if (m_iMaxLevel < pNewsServer->GetLevel()) { m_iMaxLevel = pNewsServer->GetLevel(); } for (int i = 0; i < pNewsServer->GetMaxConnections(); i++) { PooledConnection* pConnection = new PooledConnection(pNewsServer); pConnection->SetTimeout(m_iTimeout); m_Connections.push_back(pConnection); } } for (int iLevel = 0; iLevel <= m_iMaxLevel; iLevel++) { int iMaxConnectionsForLevel = 0; for (Servers::iterator it = m_Servers.begin(); it != m_Servers.end(); it++) { NewsServer* pNewsServer = *it; if (iLevel == pNewsServer->GetLevel()) { iMaxConnectionsForLevel += pNewsServer->GetMaxConnections(); } } m_Levels.push_back(iMaxConnectionsForLevel); } }
void ServerPool::InitConnections() { debug("Initializing connections in ServerPool"); m_mutexConnections.Lock(); NormalizeLevels(); m_Levels.clear(); for (Servers::iterator it = m_SortedServers.begin(); it != m_SortedServers.end(); it++) { NewsServer* pNewsServer = *it; pNewsServer->SetBlockTime(0); int iNormLevel = pNewsServer->GetNormLevel(); if (pNewsServer->GetNormLevel() > -1) { if ((int)m_Levels.size() <= iNormLevel) { m_Levels.push_back(0); } if (pNewsServer->GetActive()) { int iConnections = 0; for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++) { PooledConnection* pConnection = *it; if (pConnection->GetNewsServer() == pNewsServer) { iConnections++; } } for (int i = iConnections; i < pNewsServer->GetMaxConnections(); i++) { PooledConnection* pConnection = new PooledConnection(pNewsServer); pConnection->SetTimeout(m_iTimeout); m_Connections.push_back(pConnection); iConnections++; } m_Levels[iNormLevel] += iConnections; } } } m_iGeneration++; m_mutexConnections.Unlock(); }
/* * Calculate normalized levels for all servers. * Normalized Level means: starting from 0 with step 1. * The servers of minimum Level must be always used even if they are not active; * this is to prevent backup servers to act as main servers. **/ void ServerPool::NormalizeLevels() { if (m_Servers.empty()) { return; } std::sort(m_SortedServers.begin(), m_SortedServers.end(), CompareServers); // find minimum level int iMinLevel = m_SortedServers.front()->GetLevel(); for (Servers::iterator it = m_SortedServers.begin(); it != m_SortedServers.end(); it++) { NewsServer* pNewsServer = *it; if (pNewsServer->GetLevel() < iMinLevel) { iMinLevel = pNewsServer->GetLevel(); } } m_iMaxNormLevel = 0; int iLastLevel = iMinLevel; for (Servers::iterator it = m_SortedServers.begin(); it != m_SortedServers.end(); it++) { NewsServer* pNewsServer = *it; if ((pNewsServer->GetActive() && pNewsServer->GetMaxConnections() > 0) || (pNewsServer->GetLevel() == iMinLevel)) { if (pNewsServer->GetLevel() != iLastLevel) { m_iMaxNormLevel++; } pNewsServer->SetNormLevel(m_iMaxNormLevel); iLastLevel = pNewsServer->GetLevel(); } else { pNewsServer->SetNormLevel(-1); } } }
/* * Compute maximum number of allowed download threads **/ void QueueCoordinator::AdjustDownloadsLimit() { if (m_iServerConfigGeneration == g_pServerPool->GetGeneration()) { return; } // two extra threads for completing files (when connections are not needed) int iDownloadsLimit = 2; // allow one thread per 0-level (main) and 1-level (backup) server connection for (Servers::iterator it = g_pServerPool->GetServers()->begin(); it != g_pServerPool->GetServers()->end(); it++) { NewsServer* pNewsServer = *it; if ((pNewsServer->GetNormLevel() == 0 || pNewsServer->GetNormLevel() == 1) && pNewsServer->GetActive()) { iDownloadsLimit += pNewsServer->GetMaxConnections(); } } m_iDownloadsLimit = iDownloadsLimit; }