diff options
author | gregs <greg@10gen.com> | 2011-06-08 13:00:09 -0400 |
---|---|---|
committer | gregs <greg@10gen.com> | 2011-06-13 19:43:38 -0400 |
commit | 436a4edd9fafc134fbf86c3b127d4714de609044 (patch) | |
tree | 5936cc0113b483ddf2d99ef90dffef924a8e90bf /client | |
parent | 6296e8c7633af418c4ff3e69b59e8c7597c0d1d1 (diff) | |
download | mongo-436a4edd9fafc134fbf86c3b127d4714de609044.tar.gz |
add client socket timeout option SERVER-3220
Diffstat (limited to 'client')
-rw-r--r-- | client/connpool.cpp | 28 | ||||
-rw-r--r-- | client/connpool.h | 26 | ||||
-rw-r--r-- | client/dbclient.cpp | 11 | ||||
-rw-r--r-- | client/dbclient.h | 2 | ||||
-rw-r--r-- | client/syncclusterconnection.cpp | 16 | ||||
-rw-r--r-- | client/syncclusterconnection.h | 12 |
6 files changed, 67 insertions, 28 deletions
diff --git a/client/connpool.cpp b/client/connpool.cpp index 0b3f6a13075..ab899b0f292 100644 --- a/client/connpool.cpp +++ b/client/connpool.cpp @@ -145,7 +145,7 @@ namespace mongo { return conn; } - DBClientBase* DBConnectionPool::get(const ConnectionString& url) { + DBClientBase* DBConnectionPool::get(const ConnectionString& url, double socketTimeout) { DBClientBase * c = _get( url.toString() ); if ( c ) { onHandedOut( c ); @@ -153,13 +153,13 @@ namespace mongo { } string errmsg; - c = url.connect( errmsg ); + c = url.connect( errmsg, socketTimeout ); uassert( 13328 , _name + ": connect failed " + url.toString() + " : " + errmsg , c ); return _finishCreate( url.toString() , c ); } - DBClientBase* DBConnectionPool::get(const string& host) { + DBClientBase* DBConnectionPool::get(const string& host, double socketTimeout) { DBClientBase * c = _get( host ); if ( c ) { onHandedOut( c ); @@ -170,7 +170,7 @@ namespace mongo { ConnectionString cs = ConnectionString::parse( host , errmsg ); uassert( 13071 , (string)"invalid hostname [" + host + "]" + errmsg , cs.isValid() ); - c = cs.connect( errmsg ); + c = cs.connect( errmsg, socketTimeout ); if ( ! c ) throw SocketException( SocketException::CONNECT_ERROR , host , 11002 , str::stream() << _name << " error: " << errmsg ); return _finishCreate( host , c ); @@ -305,11 +305,19 @@ namespace mongo { ScopedDbConnection * ScopedDbConnection::steal() { assert( _conn ); - ScopedDbConnection * n = new ScopedDbConnection( _host , _conn ); + ScopedDbConnection * n = new ScopedDbConnection( _host , _conn, _socketTimeout ); _conn = 0; return n; } + 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() ) { @@ -320,12 +328,14 @@ namespace mongo { } } - ScopedDbConnection::ScopedDbConnection(const Shard& shard ) - : _host( shard.getConnString() ) , _conn( pool.get(_host) ) { + ScopedDbConnection::ScopedDbConnection(const Shard& shard, double socketTimeout ) + : _host( shard.getConnString() ) , _conn( pool.get(_host, socketTimeout) ), _socketTimeout( socketTimeout ) { + _setSocketTimeout(); } - ScopedDbConnection::ScopedDbConnection(const Shard* shard ) - : _host( shard->getConnString() ) , _conn( pool.get(_host) ) { + ScopedDbConnection::ScopedDbConnection(const Shard* shard, double socketTimeout ) + : _host( shard->getConnString() ) , _conn( pool.get(_host, socketTimeout) ), _socketTimeout( socketTimeout ) { + _setSocketTimeout(); } diff --git a/client/connpool.h b/client/connpool.h index d4fed65e7e7..3a9229f39ab 100644 --- a/client/connpool.h +++ b/client/connpool.h @@ -122,8 +122,8 @@ namespace mongo { void flush(); - DBClientBase *get(const string& host); - DBClientBase *get(const ConnectionString& host); + DBClientBase *get(const string& host, double socketTimeout = 0); + DBClientBase *get(const ConnectionString& host, double socketTimeout = 0); void release(const string& host, DBClientBase *c); @@ -192,19 +192,25 @@ namespace mongo { /** the main constructor you want to use throws UserException if can't connect */ - explicit ScopedDbConnection(const string& host) : _host(host), _conn( pool.get(host) ) {} + explicit ScopedDbConnection(const string& host, double socketTimeout = 0) : _host(host), _conn( pool.get(host, socketTimeout) ), _socketTimeout( socketTimeout ) { + _setSocketTimeout(); + } - ScopedDbConnection() : _host( "" ) , _conn(0) {} + ScopedDbConnection() : _host( "" ) , _conn(0), _socketTimeout( 0 ) {} /* @param conn - bind to an existing connection */ - ScopedDbConnection(const string& host, DBClientBase* conn ) : _host( host ) , _conn( conn ) {} + ScopedDbConnection(const string& host, DBClientBase* conn, double socketTimeout = 0 ) : _host( host ) , _conn( conn ), _socketTimeout( socketTimeout ) { + _setSocketTimeout(); + } /** throws UserException if can't connect */ - explicit ScopedDbConnection(const ConnectionString& url ) : _host(url.toString()), _conn( pool.get(url) ) {} + explicit ScopedDbConnection(const ConnectionString& url, double socketTimeout = 0 ) : _host(url.toString()), _conn( pool.get(url, socketTimeout) ), _socketTimeout( socketTimeout ) { + _setSocketTimeout(); + } /** throws UserException if can't connect */ - explicit ScopedDbConnection(const Shard& shard ); - explicit ScopedDbConnection(const Shard* shard ); + explicit ScopedDbConnection(const Shard& shard, double socketTimeout = 0 ); + explicit ScopedDbConnection(const Shard* shard, double socketTimeout = 0 ); ~ScopedDbConnection(); @@ -260,8 +266,12 @@ namespace mongo { ScopedDbConnection * steal(); private: + + void _setSocketTimeout(); + const string _host; DBClientBase *_conn; + const double _socketTimeout; }; diff --git a/client/dbclient.cpp b/client/dbclient.cpp index c079abad65e..3eb4e54303f 100644 --- a/client/dbclient.cpp +++ b/client/dbclient.cpp @@ -64,15 +64,17 @@ namespace mongo { } - DBClientBase* ConnectionString::connect( string& errmsg ) const { + DBClientBase* ConnectionString::connect( string& errmsg, double socketTimeout ) const { switch ( _type ) { case MASTER: { DBClientConnection * c = new DBClientConnection(true); + c->setSoTimeout( socketTimeout ); log(1) << "creating new connection to:" << _servers[0] << endl; if ( ! c->connect( _servers[0] , errmsg ) ) { delete c; return 0; } + log(1) << "connected connection!" << endl; return c; } @@ -93,7 +95,8 @@ namespace mongo { list<HostAndPort> l; for ( unsigned i=0; i<_servers.size(); i++ ) l.push_back( _servers[i] ); - return new SyncClusterConnection( l ); + SyncClusterConnection* c = new SyncClusterConnection( l, socketTimeout ); + return c; } case INVALID: @@ -575,6 +578,10 @@ namespace mongo { return false; } + if( _so_timeout == 0 ){ + printStackTrace(); + log() << "Connecting to server " << _serverString << " timeout " << _so_timeout << endl; + } if ( !p->connect(*server) ) { stringstream ss; ss << "couldn't connect to server " << _serverString; diff --git a/client/dbclient.h b/client/dbclient.h index f5aaef3c710..1ff085ca2dd 100644 --- a/client/dbclient.h +++ b/client/dbclient.h @@ -183,7 +183,7 @@ namespace mongo { string toString() const { return _string; } - DBClientBase* connect( string& errmsg ) const; + DBClientBase* connect( string& errmsg, double socketTimeout = 0 ) const; string getSetName() const { return _setName; } diff --git a/client/syncclusterconnection.cpp b/client/syncclusterconnection.cpp index 3c9bd926a61..80c3c5e4dee 100644 --- a/client/syncclusterconnection.cpp +++ b/client/syncclusterconnection.cpp @@ -24,7 +24,7 @@ namespace mongo { - SyncClusterConnection::SyncClusterConnection( const list<HostAndPort> & L) : _mutex("SyncClusterConnection") { + SyncClusterConnection::SyncClusterConnection( const list<HostAndPort> & L, double socketTimeout) : _mutex("SyncClusterConnection"), _socketTimeout( socketTimeout ) { { stringstream s; int n=0; @@ -38,7 +38,7 @@ namespace mongo { _connect( i->toString() ); } - SyncClusterConnection::SyncClusterConnection( string commaSeperated ) : _mutex("SyncClusterConnection") { + SyncClusterConnection::SyncClusterConnection( string commaSeperated, double socketTimeout) : _mutex("SyncClusterConnection"), _socketTimeout( socketTimeout ) { _address = commaSeperated; string::size_type idx; while ( ( idx = commaSeperated.find( ',' ) ) != string::npos ) { @@ -50,7 +50,7 @@ namespace mongo { uassert( 8004 , "SyncClusterConnection needs 3 servers" , _conns.size() == 3 ); } - SyncClusterConnection::SyncClusterConnection( string a , string b , string c ) : _mutex("SyncClusterConnection") { + SyncClusterConnection::SyncClusterConnection( string a , string b , string c, double socketTimeout) : _mutex("SyncClusterConnection"), _socketTimeout( socketTimeout ) { _address = a + "," + b + "," + c; // connect to all even if not working _connect( a ); @@ -58,7 +58,7 @@ namespace mongo { _connect( c ); } - SyncClusterConnection::SyncClusterConnection( SyncClusterConnection& prev ) : _mutex("SyncClusterConnection") { + SyncClusterConnection::SyncClusterConnection( SyncClusterConnection& prev, double socketTimeout) : _mutex("SyncClusterConnection"), _socketTimeout( socketTimeout ) { assert(0); } @@ -144,6 +144,7 @@ namespace mongo { void SyncClusterConnection::_connect( string host ) { log() << "SyncClusterConnection connecting to [" << host << "]" << endl; DBClientConnection * c = new DBClientConnection( true ); + c->setSoTimeout( _socketTimeout ); string errmsg; if ( ! c->connect( host , errmsg ) ) log() << "SyncClusterConnection connect fail to: " << host << " errmsg: " << errmsg << endl; @@ -386,4 +387,11 @@ namespace mongo { assert(0); } + void SyncClusterConnection::setAllSoTimeouts( double socketTimeout ){ + _socketTimeout = socketTimeout; + for ( size_t i=0; i<_conns.size(); i++ ) + + if( _conns[i] ) _conns[i]->setSoTimeout( socketTimeout ); + } + } diff --git a/client/syncclusterconnection.h b/client/syncclusterconnection.h index 0fefffa2d70..556b122f208 100644 --- a/client/syncclusterconnection.h +++ b/client/syncclusterconnection.h @@ -43,9 +43,9 @@ namespace mongo { /** * @param commaSeparated should be 3 hosts comma separated */ - SyncClusterConnection( const list<HostAndPort> & ); - SyncClusterConnection( string commaSeparated ); - SyncClusterConnection( string a , string b , string c ); + SyncClusterConnection( const list<HostAndPort> &, double socketTimeout = 0); + SyncClusterConnection( string commaSeparated, double socketTimeout = 0); + SyncClusterConnection( string a , string b , string c, double socketTimeout = 0 ); ~SyncClusterConnection(); /** @@ -91,8 +91,10 @@ namespace mongo { virtual ConnectionString::ConnectionType type() const { return ConnectionString::SYNC; } + void setAllSoTimeouts( double socketTimeout ); + private: - SyncClusterConnection( SyncClusterConnection& prev ); + SyncClusterConnection( SyncClusterConnection& prev, double socketTimeout = 0 ); string _toString() const; bool _commandOnActive(const string &dbname, const BSONObj& cmd, BSONObj &info, int options=0); auto_ptr<DBClientCursor> _queryOnActive(const string &ns, Query query, int nToReturn, int nToSkip, @@ -108,6 +110,8 @@ namespace mongo { mongo::mutex _mutex; vector<BSONObj> _lastErrors; + + double _socketTimeout; }; class UpdateNotTheSame : public UserException { |