PooledConnection* ConnectionPool::getOrDefault(const char* policyName, LMREG::CppTable* params)
	{
		if(!m_settings.empty())
		{
			return this->get(policyName, params);
		}
		{
			PooledConnection* cnn = NULL;
			
			JG_S::KAutoThreadMutex mx(m_mx);

			ConnectionSetting* cnnSetting = m_settings.defaultConnection();
			if(!cnnSetting) return NULL;

			ConnectionList& lst = m_cnnMap[m_settings.defaultName()];

			cnn = lst.pop_front();
			if(!cnn)
			{
				cnn = PooledConnection::Alloc(); cnn->reset();
				cnn->m_setting = cnnSetting;
			}

			if(!cnn->keepAlive())
			{
				this->release(cnn);
				return NULL;
			}

			return cnn;
		}
	}
void BloomfilterConnectionPool::recycleConnectionPool()
{
    pthread_mutex_lock(&mutex_connectionpool);
    if (connections.empty())
    {
        pthread_mutex_unlock(&mutex_connectionpool);
        return;
    }
    PooledConnection* pConn = NULL;
    for (int i = 0; i < connections.size(); i++)
    {
        pConn = connections.at(i);
        if (!pConn->isBusy())
        {
            delete pConn->getConnection();
            delete pConn;
        }
        else
        {
            delete pConn;
        }
    }
    connections.clear();
    pthread_mutex_unlock(&mutex_connectionpool);
    return;
}
//刷新连接池中所有的连接对象
void MySQLConnectionPool::refreshConnections() {
	// 确保连接池己创新存在
	pthread_mutex_lock(&mutex_connectionpool);
	if (connections.empty()) {
		pthread_mutex_unlock(&mutex_connectionpool);
		return;
	}
	
	PooledConnection *pConn = NULL;
	
	for(int i =0 ; i<connections.size(); i++) {
		
		// 获得一个连接对象
		
		pConn = connections.at(i);
		
		// 如果对象忙则等 5 秒 ,5 秒后直接刷新
		
		if (pConn->isBusy()) {
			
			wait(5000); // 等 5 秒
			
		}
		
		// 关闭此连接,用一个新的连接代替它。
		
		closeConnection(pConn->getConnection());
		
		pConn->setConnection(newConnection());
		
		pConn->setBusy(false);
		
	}
	pthread_mutex_unlock(&mutex_connectionpool);
}
//关闭连接池中所有的连接,并清空连接池
void MySQLConnectionPool::closeConnectionPool() {
	// 确保连接池存在,如果不存在,返回
	pthread_mutex_lock(&mutex_connectionpool);
	if (connections.empty()) {
		pthread_mutex_unlock(&mutex_connectionpool);
		return;
	}

	PooledConnection *pConn = NULL;

	for(int i = 0 ; i < connections.size(); i++){
		
		pConn = connections.at(i);
		
		// 如果忙,等 5 秒
		if (pConn->isBusy()) {
			wait(5000); // 等 5 秒
		}
		
		//5 秒后直接关闭它	
		closeConnection(pConn->getConnection());	
		// 从连接池向量中删除它	
		delete pConn;
		connections.erase(connections.begin()+i);
	}

	pthread_mutex_unlock(&mutex_connectionpool);
	// 置连接池为空
	connections.clear();
}
Exemple #5
0
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);
	}
}
	PooledConnection* ConnectionPool::get(const char* policyName, LMREG::CppTable* params)
	{	
		PooledConnection* cnn = NULL;
		{
			JG_S::KAutoThreadMutex mx(m_mx);
			
			ConnectionSetting* cnnSetting = (ConnectionSetting*)m_settings.callPolicy(policyName, *params);
			if(!cnnSetting) return NULL;

			const char* cnnName = cnnSetting->m_name.c_str();

			ConnectionList& lst = m_cnnMap[cnnName];
			cnn = lst.pop_front();
			if(!cnn)
			{
				cnn = PooledConnection::Alloc(); cnn->reset();
				cnn->m_setting = cnnSetting;
			}
		}
		if(!cnn->keepAlive())
		{
			this->release(cnn);
			return NULL;
		}
		return cnn;
	}
Exemple #7
0
NNTPConnection* ServerPool::GetConnection(int iLevel)
{
	PooledConnection* pConnection = NULL;

	m_mutexConnections.Lock();

	if (m_Levels[iLevel] > 0)
	{
		for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++)
		{
			PooledConnection* pConnection1 = *it;
			if (!pConnection1->GetInUse() && pConnection1->GetNewsServer()->GetLevel() == iLevel)
			{
				// free connection found, take it!
				pConnection = pConnection1;
				pConnection->SetInUse(true);
				break;
			}
		}

		m_Levels[iLevel]--;

		if (!pConnection)
		{
			error("ServerPool: internal error, no free connection found, but there should be one");
		}
	}

	m_mutexConnections.Unlock();

	return pConnection;
}
	void ConnectionPool::Execute()
	{
		while(!m_stopDesired)
		{
			time_t nowTime = time(NULL);
			if(!m_conf_lua_file.empty() && nowTime >= m_nextLoadTime)
			{
				time_t lastModify = JG_F::KFileUtil::GetLastModified(m_conf_lua_file.c_str());
				if(lastModify != m_lastModifiedTime)
				{
					PoolSettings::ConnectionSettingArray cpy(m_settings.m_settings);
					if(!m_settings.reload(m_conf_lua_file.c_str()))
					{
						Log(LOG_WARN, "warn: fail reload pool setting file '%s', recover", m_conf_lua_file.c_str());
						m_settings.m_settings = cpy;
					}
					m_lastModifiedTime = lastModify;
				}
				m_nextLoadTime = nowTime + 10;
			}
			if(nowTime > m_nextCheckIdleTime)
			{
				JG_S::KAutoThreadMutex mx(m_mx);
				ConnectionMap::iterator it = m_cnnMap.begin(), ite = m_cnnMap.end();
				for(; it != ite; it++)
				{
					ConnectionList tmp;
					ConnectionList& lst = it->second;
					PooledConnection* cnn;
					while(cnn = lst.pop_front())
					{
						if(cnn->isExpire(nowTime))
						{
							Log(LOG_DEBUG, "debug: %s expire, abandon", cnn->toString().c_str());
							cnn->destroy();
						}
						else
						{
							tmp.push_back(cnn);
						}
					}
					while(cnn = tmp.pop_front())
					{
						lst.push_back(cnn);
					}
				}
				m_nextCheckIdleTime = nowTime + 30;
			}
			msleep(100);
		}
	}
Exemple #9
0
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();
}
	void ConnectionPool::finalize()
	{
		this->stop();

		JG_S::KAutoThreadMutex mx(m_mx);
		ConnectionMap::iterator it = m_cnnMap.begin();
		ConnectionMap::iterator ite = m_cnnMap.end();
		for(; it!=ite; it++)
		{
			ConnectionList& lst = it->second;
			PooledConnection* cnn;
			while(cnn = lst.pop_front(), cnn)
				cnn->destroy();
		}
		m_cnnMap.clear();
	}
ServClient* BloomfilterConnectionPool::findFreeConnection()
{
    ServClient * conn = NULL;
    PooledConnection *pConn = NULL;
    for(int i = 0 ;i<connections.size(); i++)
    {
        pConn = connections.at(i);
        if (!pConn->isBusy())
        {
            conn = pConn->getConnection();
            pConn->setBusy(true);
            break;
        }
    }

    return conn;
}
void MySQLConnectionPool::Destroy()
{
 	pthread_mutex_lock(&mutex_connectionpool);
	if (connections.empty()) {
		pthread_mutex_unlock(&mutex_connectionpool);
		return;
	}
	
	PooledConnection *pConn = NULL;
	
	// 遍历连接池中的所有连接,找到这个要返回的连接对象
	for (int i= 0 ; i < connections.size() ; i++)
	{	
		pConn =connections.at(i);
        closeConnection(pConn->getConnection());
    }
    connections.clear();
	pthread_mutex_unlock(&mutex_connectionpool);
}
void BloomfilterConnectionPool::returnConnection(ServClient * conn)
{
    pthread_mutex_lock(&mutex_connectionpool);
    if (connections.empty())
    {
        pthread_mutex_unlock(&mutex_connectionpool);
        return;
    }

    PooledConnection* pConn = NULL;
    for (int i = 0; i < connections.size(); i++)
    {
        pConn = connections.at(i);

        if (conn == pConn->getConnection())
        {
            pConn->setBusy(false);
            break;
        }
    }
    pthread_mutex_unlock(&mutex_connectionpool);
}
//此函数返回一个数据库连接到连接池中,并把此连接置为空闲。
void MySQLConnectionPool::returnConnection(sql::Connection *conn) {
	pthread_mutex_lock(&mutex_connectionpool);
	if (connections.empty()) {
		pthread_mutex_unlock(&mutex_connectionpool);
		return;
	}
	
	PooledConnection *pConn = NULL;
	
	// 遍历连接池中的所有连接,找到这个要返回的连接对象
	for (int i= 0 ; i < connections.size() ; i++)
	{	
		pConn =connections.at(i);
		
		// 先找到连接池中的要返回的连接对象	
		if (conn == pConn->getConnection()) {
			
			// 找到了 , 设置此连接为空闲状态
			pConn->setBusy(false);
			break;	
		}		
	}
	pthread_mutex_unlock(&mutex_connectionpool);
}
Exemple #15
0
void ServerPool::LogDebugInfo()
{
	info("   ---------- ServerPool");

	info("    Max-Level: %i", m_iMaxNormLevel);

	m_mutexConnections.Lock();

	time_t tCurTime = time(NULL);

	info("    Servers: %i", m_Servers.size());
	for (Servers::iterator it = m_Servers.begin(); it != m_Servers.end(); it++)
	{
		NewsServer*  pNewsServer = *it;
		info("      %i) %s (%s): Level=%i, NormLevel=%i, BlockSec=%i", pNewsServer->GetID(), pNewsServer->GetName(),
			pNewsServer->GetHost(), pNewsServer->GetLevel(), pNewsServer->GetNormLevel(),
			pNewsServer->GetBlockTime() && pNewsServer->GetBlockTime() + m_iRetryInterval > tCurTime ?
				pNewsServer->GetBlockTime() + m_iRetryInterval - tCurTime : 0);
	}

	info("    Levels: %i", m_Levels.size());
	int index = 0;
	for (Levels::iterator it = m_Levels.begin(); it != m_Levels.end(); it++, index++)
	{
		int  iSize = *it;
		info("      %i: Free connections=%i", index, iSize);
	}

	info("    Connections: %i", m_Connections.size());
	for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++)
	{
		PooledConnection*  pConnection = *it;
		info("      %i) %s (%s): Level=%i, NormLevel=%i, InUse:%i", pConnection->GetNewsServer()->GetID(),
			pConnection->GetNewsServer()->GetName(), pConnection->GetNewsServer()->GetHost(),
			pConnection->GetNewsServer()->GetLevel(), pConnection->GetNewsServer()->GetNormLevel(),
			(int)pConnection->GetInUse());
	}

	m_mutexConnections.Unlock();
}
//查找连接池中所有的连接,查找一个可用的数据库连接
sql::Connection * MySQLConnectionPool::findFreeConnection() {
    sql::Connection * conn = NULL;
	
	PooledConnection *pConn = NULL;
	
	// 获得连接池向量中所有的对象
	for(int i = 0 ;i<connections.size(); i++) {
		
		pConn = connections.at(i);
		
		if (!pConn->isBusy()) {
			
			// 如果此对象不忙,则获得它的数据库连接并把它设为忙
			
			conn = pConn->getConnection();
			
			
			// 测试此连接是否可用
 			if (!testConnection(conn)) {
 				
 				// 如果此连接不可再用了,则创建一个新的连接,
 				
 				// 并替换此不可用的连接对象,如果创建失败,返回 null
 				
 				try {
 					conn = newConnection();
				} catch(...) {
 					return NULL;	
 				}
 				
				if (conn) {
 					pConn->setConnection(conn);	
					pConn->setBusy(true);
				} else {
					return NULL;
				}
			} else {
				pConn->setBusy(true);
			}
			break; // 己经找到一个可用的连接,退出	
		}	
	}
    //mysql_query( mysql, "SET NAMES" gbk"" );
    return conn;// 返回找到到的可用连接
}
Exemple #17
0
void ServerPool::CloseUnusedConnections()
{
	m_mutexConnections.Lock();

	time_t curtime = ::time(NULL);

	for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++)
	{
		PooledConnection* pConnection = *it;
		if (!pConnection->GetInUse() && pConnection->GetStatus() == Connection::csConnected)
		{
			int tdiff = (int)(curtime - pConnection->GetFreeTime());
			if (tdiff > CONNECTION_HOLD_SECODNS)
			{
				debug("Closing unused connection to %s", pConnection->GetHost());
				pConnection->Disconnect();
			}
		}
	}

	m_mutexConnections.Unlock();
}
Exemple #18
0
void ServerPool::CloseUnusedConnections()
{
	m_mutexConnections.Lock();

	time_t curtime = ::time(NULL);

	// close and free all connections of servers which were disabled since the last check
	int i = 0;
	for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); )
	{
		PooledConnection* pConnection = *it;
		bool bDeleted = false;

		if (!pConnection->GetInUse() &&
			(pConnection->GetNewsServer()->GetNormLevel() == -1 ||
			 !pConnection->GetNewsServer()->GetActive()))
		{
			debug("Closing (and deleting) unused connection to server%i", pConnection->GetNewsServer()->GetID());
			if (pConnection->GetStatus() == Connection::csConnected)
			{
				pConnection->Disconnect();
			}
			delete pConnection;
			m_Connections.erase(it);
			it = m_Connections.begin() + i;
			bDeleted = true;
		}

		if (!bDeleted)
		{
			it++;
			i++;
		}
	}

	// close all opened connections on levels not having any in-use connections
	for (int iLevel = 0; iLevel <= m_iMaxNormLevel; iLevel++)
	{
		// check if we have in-use connections on the level
		bool bHasInUseConnections = false;
		int iInactiveTime = 0;
		for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++)
		{
			PooledConnection* pConnection = *it;
			if (pConnection->GetNewsServer()->GetNormLevel() == iLevel)
			{
				if (pConnection->GetInUse())
				{
					bHasInUseConnections = true;
					break;
				}
				else
				{
					int tdiff = (int)(curtime - pConnection->GetFreeTime());
					if (tdiff > iInactiveTime)
					{
						iInactiveTime = tdiff;
					}
				}
			}
		}

		// if there are no in-use connections on the level and the hold time out has
		// expired - close all connections of the level.
		if (!bHasInUseConnections && iInactiveTime > CONNECTION_HOLD_SECODNS)
		{
			for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++)
			{
				PooledConnection* pConnection = *it;
				if (pConnection->GetNewsServer()->GetNormLevel() == iLevel &&
					pConnection->GetStatus() == Connection::csConnected)
				{
					debug("Closing (and keeping) unused connection to server%i", pConnection->GetNewsServer()->GetID());
					pConnection->Disconnect();
				}
			}
		}
	}

	m_mutexConnections.Unlock();
}
Exemple #19
0
NNTPConnection* ServerPool::GetConnection(int iLevel, NewsServer* pWantServer, Servers* pIgnoreServers)
{
	PooledConnection* pConnection = NULL;
	m_mutexConnections.Lock();

	time_t tCurTime = time(NULL);

	if (iLevel < (int)m_Levels.size() && m_Levels[iLevel] > 0)
	{
		Connections candidates;
		candidates.reserve(m_Connections.size());

		for (Connections::iterator it = m_Connections.begin(); it != m_Connections.end(); it++)
		{
			PooledConnection* pCandidateConnection = *it;
			NewsServer* pCandidateServer = pCandidateConnection->GetNewsServer();
			if (!pCandidateConnection->GetInUse() && pCandidateServer->GetActive() &&
				pCandidateServer->GetNormLevel() == iLevel && 
				(!pWantServer || pCandidateServer == pWantServer ||
				 (pWantServer->GetGroup() > 0 && pWantServer->GetGroup() == pCandidateServer->GetGroup())) &&
				(pCandidateConnection->GetStatus() == Connection::csConnected ||
				 !pCandidateServer->GetBlockTime() ||
				 pCandidateServer->GetBlockTime() + m_iRetryInterval <= tCurTime ||
				 pCandidateServer->GetBlockTime() > tCurTime))
			{
				// free connection found, check if it's not from the server which should be ignored
				bool bUseConnection = true;
				if (pIgnoreServers && !pWantServer)
				{
					for (Servers::iterator it = pIgnoreServers->begin(); it != pIgnoreServers->end(); it++)
					{
						NewsServer* pIgnoreServer = *it;
						if (pIgnoreServer == pCandidateServer ||
							(pIgnoreServer->GetGroup() > 0 && pIgnoreServer->GetGroup() == pCandidateServer->GetGroup() &&
							 pIgnoreServer->GetNormLevel() == pCandidateServer->GetNormLevel()))
						{
							bUseConnection = false;
							break;
						}
					}
				}

				pCandidateServer->SetBlockTime(0);

				if (bUseConnection)
				{
					candidates.push_back(pCandidateConnection);
				}
			}
		}

		if (!candidates.empty())
		{
			// Peeking a random free connection. This is better than taking the first
			// available connection because provides better distribution across news servers,
			// especially when one of servers becomes unavailable or doesn't have requested articles.
			int iRandomIndex = rand() % candidates.size();
			pConnection = candidates[iRandomIndex];
			pConnection->SetInUse(true);
		}

		if (pConnection)
		{
			m_Levels[iLevel]--;
		}
	}

	m_mutexConnections.Unlock();

	return pConnection;
}
void BloomfilterConnectionPool::closeConnectionPool()
{
#if 0
    pthread_mutex_lock(&mutex_closepool);
    if (isClosing == 1)
    {
        while (isClosing == 1)
        {
            pthread_mutex_unlock(&mutex_closepool);
            //sleep(5);
            pthread_mutex_lock(&mutex_closepool);
        }
        pthread_mutex_unlock(&mutex_closepool);
        return;
    }
    isClosing = 1;
    pthread_mutex_unlock(&mutex_closepool);
#endif
    pthread_mutex_lock(&mutex_connectionpool);
    if (connections.empty())
    {
        pthread_mutex_unlock(&mutex_connectionpool);
#if 0
        pthread_mutex_lock(&mutex_closepool);
        isClosing = 0;
        pthread_mutex_unlock(&mutex_closepool);
#endif
        return;
    }
    PooledConnection* pConn = NULL;

    int ret = connections.size();
    for (int i = 0; i < connections.size(); i++)
    {
        pConn = connections.at(i);
#if 0
        while (pConn->isBusy())
        {
            // 等50秒时间有点长,是为了防止dump时,阻塞了client的请求。找时间优化一下对这个地方的处理。
            //wait(5);
        }
#endif
        //delete pConn->getConnection();
        if (!pConn->isBusy())
        {
            delete pConn->getConnection();
            delete pConn;
        }
        else
        {
            delete pConn;
        }
        //        connections.erase(connections.begin()+i);
    }
    connections.clear();
    pthread_mutex_unlock(&mutex_connectionpool);
    //printf("close executed unlock\n");
#if 0
    pthread_mutex_lock(&mutex_closepool);
    isClosing = 0;
    pthread_mutex_unlock(&mutex_closepool);
#endif
}