summaryrefslogtreecommitdiff
path: root/src/mongo/client/connpool.cpp
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2015-06-20 00:22:50 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2015-06-20 10:56:02 -0400
commit9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch)
tree3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/client/connpool.cpp
parent01965cf52bce6976637ecb8f4a622aeb05ab256a (diff)
downloadmongo-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.cpp747
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