diff options
Diffstat (limited to 's/client.cpp')
-rw-r--r-- | s/client.cpp | 111 |
1 files changed, 58 insertions, 53 deletions
diff --git a/s/client.cpp b/s/client.cpp index b8559b6..95e3124 100644 --- a/s/client.cpp +++ b/s/client.cpp @@ -36,7 +36,7 @@ namespace mongo { - ClientInfo::ClientInfo( int clientId ) : _id( clientId ) { + ClientInfo::ClientInfo() { _cur = &_a; _prev = &_b; _autoSplitOk = true; @@ -44,13 +44,6 @@ namespace mongo { } ClientInfo::~ClientInfo() { - if ( _lastAccess ) { - scoped_lock lk( _clientsLock ); - Cache::iterator i = _clients.find( _id ); - if ( i != _clients.end() ) { - _clients.erase( i ); - } - } } void ClientInfo::addShard( const string& shard ) { @@ -79,49 +72,19 @@ namespace mongo { _cur->clear(); } - void ClientInfo::disconnect() { - _lastAccess = 0; - } - - ClientInfo * ClientInfo::get( int clientId , bool create ) { - - if ( ! clientId ) - clientId = getClientId(); - - if ( ! clientId ) { - ClientInfo * info = _tlInfo.get(); - if ( ! info ) { - info = new ClientInfo( 0 ); - _tlInfo.reset( info ); - } + ClientInfo * ClientInfo::get() { + ClientInfo * info = _tlInfo.get(); + if ( ! info ) { + info = new ClientInfo(); + _tlInfo.reset( info ); info->newRequest(); - return info; } - - scoped_lock lk( _clientsLock ); - Cache::iterator i = _clients.find( clientId ); - if ( i != _clients.end() ) - return i->second; - if ( ! create ) - return 0; - ClientInfo * info = new ClientInfo( clientId ); - _clients[clientId] = info; return info; } - void ClientInfo::disconnect( int clientId ) { - if ( ! clientId ) - return; - - scoped_lock lk( _clientsLock ); - Cache::iterator i = _clients.find( clientId ); - if ( i == _clients.end() ) - return; - - ClientInfo* ci = i->second; - ci->disconnect(); - delete ci; - _clients.erase( i ); + void ClientInfo::disconnect() { + // should be handled by TL cleanup + _lastAccess = 0; } void ClientInfo::_addWriteBack( vector<WBInfo>& all , const BSONObj& gle ) { @@ -142,14 +105,14 @@ namespace mongo { vector<BSONObj> ClientInfo::_handleWriteBacks( vector<WBInfo>& all , bool fromWriteBackListener ) { vector<BSONObj> res; + + if ( all.size() == 0 ) + return res; if ( fromWriteBackListener ) { LOG(1) << "not doing recusrive writeback" << endl; return res; } - - if ( all.size() == 0 ) - return res; for ( unsigned i=0; i<all.size(); i++ ) { res.push_back( WriteBackListener::waitFor( all[i].connectionId , all[i].id ) ); @@ -177,7 +140,21 @@ namespace mongo { ShardConnection conn( theShard , "" ); BSONObj res; - bool ok = conn->runCommand( "admin" , options , res ); + bool ok = false; + try{ + ok = conn->runCommand( "admin" , options , res ); + } + catch( std::exception &e ){ + + warning() << "Could not get last error." << e.what() << endl; + + // Catch everything that happens here, since we need to ensure we return our connection when we're + // finished. + conn.done(); + + return false; + } + res = res.getOwned(); conn.done(); @@ -205,6 +182,7 @@ namespace mongo { assert( v.size() == 1 ); result.appendElements( v[0] ); result.appendElementsUnique( res ); + result.append( "writebackGLE" , v[0] ); result.append( "initialGLEHost" , theShard ); } } @@ -217,8 +195,11 @@ namespace mongo { } BSONArrayBuilder bbb( result.subarrayStart( "shards" ) ); + BSONObjBuilder shardRawGLE; long long n = 0; + + int updatedExistingStat = 0; // 0 is none, -1 has but false, 1 has true // hit each shard vector<string> errors; @@ -228,7 +209,22 @@ namespace mongo { bbb.append( theShard ); ShardConnection conn( theShard , "" ); BSONObj res; - bool ok = conn->runCommand( "admin" , options , res ); + bool ok = false; + try { + ok = conn->runCommand( "admin" , options , res ); + shardRawGLE.append( theShard , res ); + } + catch( std::exception &e ){ + + // Safe to return here, since we haven't started any extra processing yet, just collecting + // responses. + + warning() << "Could not get last error." << e.what() << endl; + conn.done(); + + return false; + } + _addWriteBack( writebacks, res ); string temp = DBClientWithCommands::getLastErrorString( res ); @@ -236,13 +232,24 @@ namespace mongo { errors.push_back( temp ); errorObjects.push_back( res ); } + n += res["n"].numberLong(); + if ( res["updatedExisting"].type() ) { + if ( res["updatedExisting"].trueValue() ) + updatedExistingStat = 1; + else if ( updatedExistingStat == 0 ) + updatedExistingStat = -1; + } + conn.done(); } bbb.done(); + result.append( "shardRawGLE" , shardRawGLE.obj() ); result.appendNumber( "n" , n ); + if ( updatedExistingStat ) + result.appendBool( "updatedExisting" , updatedExistingStat > 0 ); // hit other machines just to block for ( set<string>::const_iterator i=sinceLastGetError().begin(); i!=sinceLastGetError().end(); ++i ) { @@ -285,8 +292,6 @@ namespace mongo { return true; } - ClientInfo::Cache& ClientInfo::_clients = *(new ClientInfo::Cache()); - mongo::mutex ClientInfo::_clientsLock("_clientsLock"); boost::thread_specific_ptr<ClientInfo> ClientInfo::_tlInfo; } // namespace mongo |