diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 00:22:50 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 10:56:02 -0400 |
commit | 9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch) | |
tree | 3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/client/connpool.cpp | |
parent | 01965cf52bce6976637ecb8f4a622aeb05ab256a (diff) | |
download | mongo-9c2ed42daa8fbbef4a919c21ec564e2db55e8d60.tar.gz |
SERVER-18579: Clang-Format - reformat code, no comment reflow
Diffstat (limited to 'src/mongo/client/connpool.cpp')
-rw-r--r-- | src/mongo/client/connpool.cpp | 747 |
1 files changed, 369 insertions, 378 deletions
diff --git a/src/mongo/client/connpool.cpp b/src/mongo/client/connpool.cpp index b56bec49551..e691baafc57 100644 --- a/src/mongo/client/connpool.cpp +++ b/src/mongo/client/connpool.cpp @@ -43,489 +43,480 @@ namespace mongo { - using std::endl; - using std::list; - using std::map; - using std::set; - using std::string; - using std::vector; - - // ------ PoolForHost ------ - - PoolForHost::~PoolForHost() { +using std::endl; +using std::list; +using std::map; +using std::set; +using std::string; +using std::vector; + +// ------ PoolForHost ------ + +PoolForHost::~PoolForHost() { + clear(); +} + +void PoolForHost::clear() { + while (!_pool.empty()) { + StoredConnection sc = _pool.top(); + delete sc.conn; + _pool.pop(); + } +} + +void PoolForHost::done(DBConnectionPool* pool, DBClientBase* c) { + bool isFailed = c->isFailed(); + + // Remember that this host had a broken connection for later + if (isFailed) + reportBadConnectionAt(c->getSockCreationMicroSec()); + + if (isFailed || + // Another (later) connection was reported as broken to this host + (c->getSockCreationMicroSec() < _minValidCreationTimeMicroSec) || + // We have a pool size that we need to enforce + (_maxPoolSize >= 0 && static_cast<int>(_pool.size()) >= _maxPoolSize)) { + pool->onDestroy(c); + delete c; + } else { + // The connection is probably fine, save for later + _pool.push(c); + } +} + +void PoolForHost::reportBadConnectionAt(uint64_t microSec) { + if (microSec != DBClientBase::INVALID_SOCK_CREATION_TIME && + microSec > _minValidCreationTimeMicroSec) { + _minValidCreationTimeMicroSec = microSec; + log() << "Detected bad connection created at " << _minValidCreationTimeMicroSec + << " microSec, clearing pool for " << _hostName << " of " << _pool.size() + << " connections" << endl; clear(); } +} - void PoolForHost::clear() { - while ( ! _pool.empty() ) { - StoredConnection sc = _pool.top(); - delete sc.conn; - _pool.pop(); - } - } - - void PoolForHost::done(DBConnectionPool* pool, DBClientBase* c) { +bool PoolForHost::isBadSocketCreationTime(uint64_t microSec) { + return microSec != DBClientBase::INVALID_SOCK_CREATION_TIME && + microSec <= _minValidCreationTimeMicroSec; +} - bool isFailed = c->isFailed(); +DBClientBase* PoolForHost::get(DBConnectionPool* pool, double socketTimeout) { + time_t now = time(0); - // Remember that this host had a broken connection for later - if (isFailed) reportBadConnectionAt(c->getSockCreationMicroSec()); + while (!_pool.empty()) { + StoredConnection sc = _pool.top(); + _pool.pop(); - if (isFailed || - // Another (later) connection was reported as broken to this host - (c->getSockCreationMicroSec() < _minValidCreationTimeMicroSec) || - // We have a pool size that we need to enforce - (_maxPoolSize >= 0 && static_cast<int>(_pool.size()) >= _maxPoolSize)) { - pool->onDestroy(c); - delete c; - } - else { - // The connection is probably fine, save for later - _pool.push(c); + if (!sc.ok(now)) { + pool->onDestroy(sc.conn); + delete sc.conn; + continue; } - } - void PoolForHost::reportBadConnectionAt(uint64_t microSec) { - if (microSec != DBClientBase::INVALID_SOCK_CREATION_TIME && - microSec > _minValidCreationTimeMicroSec) { - _minValidCreationTimeMicroSec = microSec; - log() << "Detected bad connection created at " << _minValidCreationTimeMicroSec - << " microSec, clearing pool for " << _hostName - << " of " << _pool.size() << " connections" << endl; - clear(); - } - } + verify(sc.conn->getSoTimeout() == socketTimeout); - bool PoolForHost::isBadSocketCreationTime(uint64_t microSec) { - return microSec != DBClientBase::INVALID_SOCK_CREATION_TIME && - microSec <= _minValidCreationTimeMicroSec; + return sc.conn; } - DBClientBase * PoolForHost::get( DBConnectionPool * pool , double socketTimeout ) { - - time_t now = time(0); - - while ( ! _pool.empty() ) { - StoredConnection sc = _pool.top(); - _pool.pop(); - - if ( ! sc.ok( now ) ) { - pool->onDestroy( sc.conn ); - delete sc.conn; - continue; - } - - verify( sc.conn->getSoTimeout() == socketTimeout ); - - return sc.conn; - - } + return NULL; +} - return NULL; +void PoolForHost::flush() { + while (!_pool.empty()) { + StoredConnection c = _pool.top(); + _pool.pop(); + delete c.conn; } +} - void PoolForHost::flush() { - while (!_pool.empty()) { - StoredConnection c = _pool.top(); - _pool.pop(); - delete c.conn; - } - } +void PoolForHost::getStaleConnections(vector<DBClientBase*>& stale) { + time_t now = time(0); - void PoolForHost::getStaleConnections( vector<DBClientBase*>& stale ) { - time_t now = time(0); + vector<StoredConnection> all; + while (!_pool.empty()) { + StoredConnection c = _pool.top(); + _pool.pop(); - vector<StoredConnection> all; - while ( ! _pool.empty() ) { - StoredConnection c = _pool.top(); - _pool.pop(); - - if ( c.ok( now ) ) - all.push_back( c ); - else - stale.push_back( c.conn ); - } + if (c.ok(now)) + all.push_back(c); + else + stale.push_back(c.conn); + } - for ( size_t i=0; i<all.size(); i++ ) { - _pool.push( all[i] ); - } + for (size_t i = 0; i < all.size(); i++) { + _pool.push(all[i]); } +} - PoolForHost::StoredConnection::StoredConnection( DBClientBase * c ) { - conn = c; - when = time(0); - } +PoolForHost::StoredConnection::StoredConnection(DBClientBase* c) { + conn = c; + when = time(0); +} - bool PoolForHost::StoredConnection::ok( time_t now ) { - // Poke the connection to see if we're still ok - return conn->isStillConnected(); - } +bool PoolForHost::StoredConnection::ok(time_t now) { + // Poke the connection to see if we're still ok + return conn->isStillConnected(); +} - void PoolForHost::createdOne( DBClientBase * base) { - if ( _created == 0 ) - _type = base->type(); - _created++; - } +void PoolForHost::createdOne(DBClientBase* base) { + if (_created == 0) + _type = base->type(); + _created++; +} - void PoolForHost::initializeHostName(const std::string& hostName) { - if (_hostName.empty()) { - _hostName = hostName; - } +void PoolForHost::initializeHostName(const std::string& hostName) { + if (_hostName.empty()) { + _hostName = hostName; } +} - // ------ DBConnectionPool ------ +// ------ DBConnectionPool ------ - const int PoolForHost::kPoolSizeUnlimited(-1); +const int PoolForHost::kPoolSizeUnlimited(-1); - DBConnectionPool::DBConnectionPool() - : _name( "dbconnectionpool" ) , - _maxPoolSize(PoolForHost::kPoolSizeUnlimited) , - _hooks( new list<DBConnectionHook*>() ) { - } +DBConnectionPool::DBConnectionPool() + : _name("dbconnectionpool"), + _maxPoolSize(PoolForHost::kPoolSizeUnlimited), + _hooks(new list<DBConnectionHook*>()) {} - DBClientBase* DBConnectionPool::_get(const string& ident , double socketTimeout ) { - uassert(17382, "Can't use connection pool during shutdown", - !inShutdown()); +DBClientBase* DBConnectionPool::_get(const string& ident, double socketTimeout) { + uassert(17382, "Can't use connection pool during shutdown", !inShutdown()); + stdx::lock_guard<stdx::mutex> L(_mutex); + PoolForHost& p = _pools[PoolKey(ident, socketTimeout)]; + p.setMaxPoolSize(_maxPoolSize); + p.initializeHostName(ident); + return p.get(this, socketTimeout); +} + +DBClientBase* DBConnectionPool::_finishCreate(const string& host, + double socketTimeout, + DBClientBase* conn) { + { stdx::lock_guard<stdx::mutex> L(_mutex); - PoolForHost& p = _pools[PoolKey(ident,socketTimeout)]; + PoolForHost& p = _pools[PoolKey(host, socketTimeout)]; p.setMaxPoolSize(_maxPoolSize); - p.initializeHostName(ident); - return p.get( this , socketTimeout ); + p.initializeHostName(host); + p.createdOne(conn); } - DBClientBase* DBConnectionPool::_finishCreate( const string& host , double socketTimeout , DBClientBase* conn ) { - { - stdx::lock_guard<stdx::mutex> L(_mutex); - PoolForHost& p = _pools[PoolKey(host,socketTimeout)]; - p.setMaxPoolSize(_maxPoolSize); - p.initializeHostName(host); - p.createdOne( conn ); - } - + try { + onCreate(conn); + onHandedOut(conn); + } catch (std::exception&) { + delete conn; + throw; + } + + return conn; +} + +DBClientBase* DBConnectionPool::get(const ConnectionString& url, double socketTimeout) { + DBClientBase* c = _get(url.toString(), socketTimeout); + if (c) { try { - onCreate( conn ); - onHandedOut( conn ); - } - catch ( std::exception & ) { - delete conn; + onHandedOut(c); + } catch (std::exception&) { + delete c; throw; } - - return conn; + return c; } - DBClientBase* DBConnectionPool::get(const ConnectionString& url, double socketTimeout) { - DBClientBase * c = _get( url.toString() , socketTimeout ); - if ( c ) { - try { - onHandedOut( c ); - } - catch ( std::exception& ) { - delete c; - throw; - } - return c; - } + string errmsg; + c = url.connect(errmsg, socketTimeout); + uassert(13328, _name + ": connect failed " + url.toString() + " : " + errmsg, c); - string errmsg; - c = url.connect( errmsg, socketTimeout ); - uassert( 13328 , _name + ": connect failed " + url.toString() + " : " + errmsg , c ); + return _finishCreate(url.toString(), socketTimeout, c); +} - return _finishCreate( url.toString() , socketTimeout , c ); +DBClientBase* DBConnectionPool::get(const string& host, double socketTimeout) { + DBClientBase* c = _get(host, socketTimeout); + if (c) { + try { + onHandedOut(c); + } catch (std::exception&) { + delete c; + throw; + } + return c; } - DBClientBase* DBConnectionPool::get(const string& host, double socketTimeout) { - DBClientBase * c = _get( host , socketTimeout ); - if ( c ) { - try { - onHandedOut( c ); - } - catch ( std::exception& ) { - delete c; - throw; - } - return c; - } + const ConnectionString cs(uassertStatusOK(ConnectionString::parse(host))); - const ConnectionString cs(uassertStatusOK(ConnectionString::parse(host))); + string errmsg; + c = cs.connect(errmsg, socketTimeout); + if (!c) + throw SocketException(SocketException::CONNECT_ERROR, + host, + 11002, + str::stream() << _name << " error: " << errmsg); + return _finishCreate(host, socketTimeout, c); +} - string errmsg; - c = cs.connect( errmsg, socketTimeout ); - if ( ! c ) - throw SocketException( SocketException::CONNECT_ERROR , host , 11002 , str::stream() << _name << " error: " << errmsg ); - return _finishCreate( host , socketTimeout , c ); +void DBConnectionPool::onRelease(DBClientBase* conn) { + if (_hooks->empty()) { + return; } - void DBConnectionPool::onRelease(DBClientBase* conn) { - if (_hooks->empty()) { - return; - } - - for (list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++) { - (*i)->onRelease( conn ); - } + for (list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++) { + (*i)->onRelease(conn); } +} - void DBConnectionPool::release(const string& host, DBClientBase *c) { - onRelease(c); +void DBConnectionPool::release(const string& host, DBClientBase* c) { + onRelease(c); - stdx::lock_guard<stdx::mutex> L(_mutex); - _pools[PoolKey(host,c->getSoTimeout())].done(this,c); - } + stdx::lock_guard<stdx::mutex> L(_mutex); + _pools[PoolKey(host, c->getSoTimeout())].done(this, c); +} - DBConnectionPool::~DBConnectionPool() { - // connection closing is handled by ~PoolForHost - } +DBConnectionPool::~DBConnectionPool() { + // connection closing is handled by ~PoolForHost +} - void DBConnectionPool::flush() { - stdx::lock_guard<stdx::mutex> L(_mutex); - for ( PoolMap::iterator i = _pools.begin(); i != _pools.end(); i++ ) { - PoolForHost& p = i->second; - p.flush(); - } +void DBConnectionPool::flush() { + stdx::lock_guard<stdx::mutex> L(_mutex); + for (PoolMap::iterator i = _pools.begin(); i != _pools.end(); i++) { + PoolForHost& p = i->second; + p.flush(); } +} - void DBConnectionPool::clear() { - stdx::lock_guard<stdx::mutex> L(_mutex); - LOG(2) << "Removing connections on all pools owned by " << _name << endl; - for (PoolMap::iterator iter = _pools.begin(); iter != _pools.end(); ++iter) { - iter->second.clear(); - } +void DBConnectionPool::clear() { + stdx::lock_guard<stdx::mutex> L(_mutex); + LOG(2) << "Removing connections on all pools owned by " << _name << endl; + for (PoolMap::iterator iter = _pools.begin(); iter != _pools.end(); ++iter) { + iter->second.clear(); } +} - void DBConnectionPool::removeHost( const string& host ) { - stdx::lock_guard<stdx::mutex> L(_mutex); - LOG(2) << "Removing connections from all pools for host: " << host << endl; - for ( PoolMap::iterator i = _pools.begin(); i != _pools.end(); ++i ) { - const string& poolHost = i->first.ident; - if ( !serverNameCompare()(host, poolHost) && !serverNameCompare()(poolHost, host) ) { - // hosts are the same - i->second.clear(); - } +void DBConnectionPool::removeHost(const string& host) { + stdx::lock_guard<stdx::mutex> L(_mutex); + LOG(2) << "Removing connections from all pools for host: " << host << endl; + for (PoolMap::iterator i = _pools.begin(); i != _pools.end(); ++i) { + const string& poolHost = i->first.ident; + if (!serverNameCompare()(host, poolHost) && !serverNameCompare()(poolHost, host)) { + // hosts are the same + i->second.clear(); } } +} - void DBConnectionPool::addHook( DBConnectionHook * hook ) { - _hooks->push_back( hook ); - } +void DBConnectionPool::addHook(DBConnectionHook* hook) { + _hooks->push_back(hook); +} - void DBConnectionPool::onCreate( DBClientBase * conn ) { - if ( _hooks->size() == 0 ) - return; +void DBConnectionPool::onCreate(DBClientBase* conn) { + if (_hooks->size() == 0) + return; - for ( list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++ ) { - (*i)->onCreate( conn ); - } + for (list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++) { + (*i)->onCreate(conn); } +} - void DBConnectionPool::onHandedOut( DBClientBase * conn ) { - if ( _hooks->size() == 0 ) - return; +void DBConnectionPool::onHandedOut(DBClientBase* conn) { + if (_hooks->size() == 0) + return; - for ( list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++ ) { - (*i)->onHandedOut( conn ); - } + for (list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++) { + (*i)->onHandedOut(conn); } +} - void DBConnectionPool::onDestroy( DBClientBase * conn ) { - if ( _hooks->size() == 0 ) - return; +void DBConnectionPool::onDestroy(DBClientBase* conn) { + if (_hooks->size() == 0) + return; - for ( list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++ ) { - (*i)->onDestroy( conn ); - } + for (list<DBConnectionHook*>::iterator i = _hooks->begin(); i != _hooks->end(); i++) { + (*i)->onDestroy(conn); } +} - void DBConnectionPool::appendInfo( BSONObjBuilder& b ) { +void DBConnectionPool::appendInfo(BSONObjBuilder& b) { + int avail = 0; + long long created = 0; - int avail = 0; - long long created = 0; + map<ConnectionString::ConnectionType, long long> createdByType; - map<ConnectionString::ConnectionType,long long> createdByType; - - BSONObjBuilder bb( b.subobjStart( "hosts" ) ); - { - stdx::lock_guard<stdx::mutex> lk( _mutex ); - for ( PoolMap::iterator i=_pools.begin(); i!=_pools.end(); ++i ) { - if ( i->second.numCreated() == 0 ) - continue; + BSONObjBuilder bb(b.subobjStart("hosts")); + { + stdx::lock_guard<stdx::mutex> lk(_mutex); + for (PoolMap::iterator i = _pools.begin(); i != _pools.end(); ++i) { + if (i->second.numCreated() == 0) + continue; - string s = str::stream() << i->first.ident << "::" << i->first.timeout; + string s = str::stream() << i->first.ident << "::" << i->first.timeout; - BSONObjBuilder temp( bb.subobjStart( s ) ); - temp.append( "available" , i->second.numAvailable() ); - temp.appendNumber( "created" , i->second.numCreated() ); - temp.done(); + BSONObjBuilder temp(bb.subobjStart(s)); + temp.append("available", i->second.numAvailable()); + temp.appendNumber("created", i->second.numCreated()); + temp.done(); - avail += i->second.numAvailable(); - created += i->second.numCreated(); + avail += i->second.numAvailable(); + created += i->second.numCreated(); - long long& x = createdByType[i->second.type()]; - x += i->second.numCreated(); - } - } - bb.done(); - - // Always report all replica sets being tracked - BSONObjBuilder setBuilder(b.subobjStart("replicaSets")); - globalRSMonitorManager.report(&setBuilder); - setBuilder.done(); - - { - BSONObjBuilder temp( bb.subobjStart( "createdByType" ) ); - for ( map<ConnectionString::ConnectionType,long long>::iterator i=createdByType.begin(); i!=createdByType.end(); ++i ) { - temp.appendNumber( ConnectionString::typeToString( i->first ) , i->second ); - } - temp.done(); + long long& x = createdByType[i->second.type()]; + x += i->second.numCreated(); } - - b.append( "totalAvailable" , avail ); - b.appendNumber( "totalCreated" , created ); } + bb.done(); - bool DBConnectionPool::serverNameCompare::operator()( const string& a , const string& b ) const{ - const char* ap = a.c_str(); - const char* bp = b.c_str(); - - while (true){ - if (*ap == '\0' || *ap == '/'){ - if (*bp == '\0' || *bp == '/') - return false; // equal strings - else - return true; // a is shorter - } + // Always report all replica sets being tracked + BSONObjBuilder setBuilder(b.subobjStart("replicaSets")); + globalRSMonitorManager.report(&setBuilder); + setBuilder.done(); - if (*bp == '\0' || *bp == '/') - return false; // b is shorter - - if ( *ap < *bp) - return true; - else if (*ap > *bp) - return false; - - ++ap; - ++bp; + { + BSONObjBuilder temp(bb.subobjStart("createdByType")); + for (map<ConnectionString::ConnectionType, long long>::iterator i = createdByType.begin(); + i != createdByType.end(); + ++i) { + temp.appendNumber(ConnectionString::typeToString(i->first), i->second); } - verify(false); + temp.done(); } - - bool DBConnectionPool::poolKeyCompare::operator()( const PoolKey& a , const PoolKey& b ) const { - if (DBConnectionPool::serverNameCompare()( a.ident , b.ident )) - return true; - - if (DBConnectionPool::serverNameCompare()( b.ident , a.ident )) - return false; - return a.timeout < b.timeout; - } + b.append("totalAvailable", avail); + b.appendNumber("totalCreated", created); +} - bool DBConnectionPool::isConnectionGood(const string& hostName, DBClientBase* conn) { - if (conn == NULL) { - return false; - } +bool DBConnectionPool::serverNameCompare::operator()(const string& a, const string& b) const { + const char* ap = a.c_str(); + const char* bp = b.c_str(); - if (conn->isFailed()) { - return false; - } - - { - stdx::lock_guard<stdx::mutex> sl(_mutex); - PoolForHost& pool = _pools[PoolKey(hostName, conn->getSoTimeout())]; - if (pool.isBadSocketCreationTime(conn->getSockCreationMicroSec())) { - return false; - } + while (true) { + if (*ap == '\0' || *ap == '/') { + if (*bp == '\0' || *bp == '/') + return false; // equal strings + else + return true; // a is shorter } - return true; - } + if (*bp == '\0' || *bp == '/') + return false; // b is shorter - void DBConnectionPool::taskDoWork() { - vector<DBClientBase*> toDelete; - - { - // we need to get the connections inside the lock - // but we can actually delete them outside - stdx::lock_guard<stdx::mutex> lk( _mutex ); - for ( PoolMap::iterator i=_pools.begin(); i!=_pools.end(); ++i ) { - i->second.getStaleConnections( toDelete ); - } - } + if (*ap < *bp) + return true; + else if (*ap > *bp) + return false; - for ( size_t i=0; i<toDelete.size(); i++ ) { - try { - onDestroy( toDelete[i] ); - delete toDelete[i]; - } - catch ( ... ) { - // we don't care if there was a socket error - } - } + ++ap; + ++bp; } + verify(false); +} - // ------ ScopedDbConnection ------ +bool DBConnectionPool::poolKeyCompare::operator()(const PoolKey& a, const PoolKey& b) const { + if (DBConnectionPool::serverNameCompare()(a.ident, b.ident)) + return true; - ScopedDbConnection::ScopedDbConnection(const std::string& host, double socketTimeout) - : _host(host), - _conn(globalConnPool.get(host, socketTimeout)), - _socketTimeout(socketTimeout) { + if (DBConnectionPool::serverNameCompare()(b.ident, a.ident)) + return false; - _setSocketTimeout(); - } + return a.timeout < b.timeout; +} - ScopedDbConnection::ScopedDbConnection(const ConnectionString& host, double socketTimeout) - : _host(host.toString()), - _conn(globalConnPool.get(host, socketTimeout)), - _socketTimeout(socketTimeout) { +bool DBConnectionPool::isConnectionGood(const string& hostName, DBClientBase* conn) { + if (conn == NULL) { + return false; + } - _setSocketTimeout(); + if (conn->isFailed()) { + return false; } - void ScopedDbConnection::done() { - if (!_conn) { - return; + { + stdx::lock_guard<stdx::mutex> sl(_mutex); + PoolForHost& pool = _pools[PoolKey(hostName, conn->getSoTimeout())]; + if (pool.isBadSocketCreationTime(conn->getSockCreationMicroSec())) { + return false; } - - globalConnPool.release(_host, _conn); - _conn = NULL; } - void ScopedDbConnection::_setSocketTimeout(){ - if( ! _conn ) return; - if( _conn->type() == ConnectionString::MASTER ) - (( DBClientConnection* ) _conn)->setSoTimeout( _socketTimeout ); - else if( _conn->type() == ConnectionString::SYNC ) - (( SyncClusterConnection* ) _conn)->setAllSoTimeouts( _socketTimeout ); + return true; +} + +void DBConnectionPool::taskDoWork() { + vector<DBClientBase*> toDelete; + + { + // we need to get the connections inside the lock + // but we can actually delete them outside + stdx::lock_guard<stdx::mutex> lk(_mutex); + for (PoolMap::iterator i = _pools.begin(); i != _pools.end(); ++i) { + i->second.getStaleConnections(toDelete); + } } - ScopedDbConnection::~ScopedDbConnection() { - if ( _conn ) { - if (_conn->isFailed()) { - if (_conn->getSockCreationMicroSec() == - DBClientBase::INVALID_SOCK_CREATION_TIME) { - kill(); - } - else { - // The pool takes care of deleting the failed connection - this - // will also trigger disposal of older connections in the pool - done(); - } - } - else { - /* see done() comments above for why we log this line */ - log() << "scoped connection to " << _conn->getServerAddress() - << " not being returned to the pool" << endl; + for (size_t i = 0; i < toDelete.size(); i++) { + try { + onDestroy(toDelete[i]); + delete toDelete[i]; + } catch (...) { + // we don't care if there was a socket error + } + } +} + +// ------ ScopedDbConnection ------ + +ScopedDbConnection::ScopedDbConnection(const std::string& host, double socketTimeout) + : _host(host), _conn(globalConnPool.get(host, socketTimeout)), _socketTimeout(socketTimeout) { + _setSocketTimeout(); +} + +ScopedDbConnection::ScopedDbConnection(const ConnectionString& host, double socketTimeout) + : _host(host.toString()), + _conn(globalConnPool.get(host, socketTimeout)), + _socketTimeout(socketTimeout) { + _setSocketTimeout(); +} + +void ScopedDbConnection::done() { + if (!_conn) { + return; + } + + globalConnPool.release(_host, _conn); + _conn = NULL; +} + +void ScopedDbConnection::_setSocketTimeout() { + if (!_conn) + return; + if (_conn->type() == ConnectionString::MASTER) + ((DBClientConnection*)_conn)->setSoTimeout(_socketTimeout); + else if (_conn->type() == ConnectionString::SYNC) + ((SyncClusterConnection*)_conn)->setAllSoTimeouts(_socketTimeout); +} + +ScopedDbConnection::~ScopedDbConnection() { + if (_conn) { + if (_conn->isFailed()) { + if (_conn->getSockCreationMicroSec() == DBClientBase::INVALID_SOCK_CREATION_TIME) { kill(); + } else { + // The pool takes care of deleting the failed connection - this + // will also trigger disposal of older connections in the pool + done(); } + } else { + /* see done() comments above for why we log this line */ + log() << "scoped connection to " << _conn->getServerAddress() + << " not being returned to the pool" << endl; + kill(); } } +} - void ScopedDbConnection::clearPool() { - globalConnPool.clear(); - } +void ScopedDbConnection::clearPool() { + globalConnPool.clear(); +} - AtomicInt32 AScopedConnection::_numConnections; +AtomicInt32 AScopedConnection::_numConnections; -} // namespace mongo +} // namespace mongo |