summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorgregs <greg@10gen.com>2011-06-08 13:00:09 -0400
committergregs <greg@10gen.com>2011-06-13 19:43:38 -0400
commit436a4edd9fafc134fbf86c3b127d4714de609044 (patch)
tree5936cc0113b483ddf2d99ef90dffef924a8e90bf /client
parent6296e8c7633af418c4ff3e69b59e8c7597c0d1d1 (diff)
downloadmongo-436a4edd9fafc134fbf86c3b127d4714de609044.tar.gz
add client socket timeout option SERVER-3220
Diffstat (limited to 'client')
-rw-r--r--client/connpool.cpp28
-rw-r--r--client/connpool.h26
-rw-r--r--client/dbclient.cpp11
-rw-r--r--client/dbclient.h2
-rw-r--r--client/syncclusterconnection.cpp16
-rw-r--r--client/syncclusterconnection.h12
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 {