diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-12-27 16:44:15 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-12-27 16:44:15 -0500 |
commit | 224a70df915283c9ad2f64b31556875497fdfba8 (patch) | |
tree | 3acba3e12b24274cc17ef16753b2d4dcc0391a7a | |
parent | 54ebaf04cc49e585f5144e4ad7044f69b2afa72f (diff) | |
download | mongo-224a70df915283c9ad2f64b31556875497fdfba8.tar.gz |
move getLastError code to client.cpp so can access not only through command interface
-rw-r--r-- | s/client.cpp | 152 | ||||
-rw-r--r-- | s/client.h | 17 | ||||
-rw-r--r-- | s/commands_admin.cpp | 121 |
3 files changed, 153 insertions, 137 deletions
diff --git a/s/client.cpp b/s/client.cpp index bc07e58414c..0ce5cc8f1ca 100644 --- a/s/client.cpp +++ b/s/client.cpp @@ -1,20 +1,20 @@ // s/client.cpp /** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ + * Copyright (C) 2008 10gen Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ #include "pch.h" #include "server.h" @@ -32,7 +32,7 @@ #include "stats.h" #include "cursors.h" #include "grid.h" - +#include "s/writeback_listener.h" namespace mongo { @@ -123,6 +123,128 @@ namespace mongo { _clients.erase( i ); } + void ClientInfo::_addWriteBack( vector<OID>& all , const BSONObj& o ){ + BSONElement e = o["writeback"]; + + if ( e.type() == jstOID ) + all.push_back( e.OID() ); + } + + void ClientInfo::_handleWriteBacks( vector<OID>& all ){ + if ( all.size() == 0 ) + return; + + for ( unsigned i=0; i<all.size(); i++ ){ + WriteBackListener::waitFor( all[i] ); + } + } + + + + bool ClientInfo::getLastError( const BSONObj& options , BSONObjBuilder& result ){ + set<string> * shards = getPrev(); + + if ( shards->size() == 0 ){ + result.appendNull( "err" ); + return true; + } + + vector<OID> writebacks; + + // handle single server + if ( shards->size() == 1 ){ + string theShard = *(shards->begin() ); + result.append( "theshard" , theShard.c_str() ); + ShardConnection conn( theShard , "" ); + BSONObj res; + bool ok = conn->runCommand( "admin" , options , res ); + //log() << "\t" << res << endl; + result.appendElements( res ); + conn.done(); + result.append( "singleShard" , theShard ); + _addWriteBack( writebacks , res ); + + // hit other machines just to block + for ( set<string>::const_iterator i=sinceLastGetError().begin(); i!=sinceLastGetError().end(); ++i ){ + string temp = *i; + if ( temp == theShard ) + continue; + + ShardConnection conn( temp , "" ); + _addWriteBack( writebacks , conn->getLastErrorDetailed() ); + conn.done(); + } + clearSinceLastGetError(); + _handleWriteBacks( writebacks ); + return ok; + } + + BSONArrayBuilder bbb( result.subarrayStart( "shards" ) ); + + long long n = 0; + + // hit each shard + vector<string> errors; + vector<BSONObj> errorObjects; + for ( set<string>::iterator i = shards->begin(); i != shards->end(); i++ ){ + string theShard = *i; + bbb.append( theShard ); + ShardConnection conn( theShard , "" ); + BSONObj res; + bool ok = conn->runCommand( "admin" , options , res ); + _addWriteBack( writebacks, res ); + string temp = DBClientWithCommands::getLastErrorString( res ); + if ( ok == false || temp.size() ){ + errors.push_back( temp ); + errorObjects.push_back( res ); + } + n += res["n"].numberLong(); + conn.done(); + } + + bbb.done(); + + result.appendNumber( "n" , n ); + + // hit other machines just to block + for ( set<string>::const_iterator i=sinceLastGetError().begin(); i!=sinceLastGetError().end(); ++i ){ + string temp = *i; + if ( shards->count( temp ) ) + continue; + + ShardConnection conn( temp , "" ); + _addWriteBack( writebacks, conn->getLastErrorDetailed() ); + conn.done(); + } + clearSinceLastGetError(); + + if ( errors.size() == 0 ){ + result.appendNull( "err" ); + _handleWriteBacks( writebacks ); + return true; + } + + result.append( "err" , errors[0].c_str() ); + + { // errs + BSONArrayBuilder all( result.subarrayStart( "errs" ) ); + for ( unsigned i=0; i<errors.size(); i++ ){ + all.append( errors[i].c_str() ); + } + all.done(); + } + + { // errObjects + BSONArrayBuilder all( result.subarrayStart( "errObjects" ) ); + for ( unsigned i=0; i<errorObjects.size(); i++ ){ + all.append( errorObjects[i] ); + } + all.done(); + } + _handleWriteBacks( writebacks ); + return true; + } + ClientInfo::Cache& ClientInfo::_clients = *(new ClientInfo::Cache()); mongo::mutex ClientInfo::_clientsLock("_clientsLock"); boost::thread_specific_ptr<ClientInfo> ClientInfo::_tlInfo; diff --git a/s/client.h b/s/client.h index f3d2daa854f..60a05d92aad 100644 --- a/s/client.h +++ b/s/client.h @@ -65,12 +65,25 @@ namespace mongo { */ void clearSinceLastGetError(){ _sinceLastGetError.clear(); } + /** + * calls getLastError + * resets shards since get last error + */ + bool getLastError( const BSONObj& options , BSONObjBuilder& result ); + + static ClientInfo * get( int clientId = 0 , bool create = true ); static void disconnect( int clientId ); private: - int _id; - string _remote; + + // for getLastError + void _addWriteBack( vector<OID>& all , const BSONObj& o ); + void _handleWriteBacks( vector<OID>& all ); + + + int _id; // unique client id + string _remote; // server:port of remote socket end // we use _a and _b to store shards we've talked to on the current request and the previous // we use 2 so we can flip for getLastError type operations diff --git a/s/commands_admin.cpp b/s/commands_admin.cpp index 47603c70ca2..0628cb40ebf 100644 --- a/s/commands_admin.cpp +++ b/s/commands_admin.cpp @@ -832,22 +832,6 @@ namespace mongo { } CmdShardingGetLastError() : Command("getLastError" , false , "getlasterror") { } - void addWriteBack( vector<OID>& all , const BSONObj& o ){ - BSONElement e = o["writeback"]; - - if ( e.type() == jstOID ) - all.push_back( e.OID() ); - } - - void handleWriteBacks( vector<OID>& all ){ - if ( all.size() == 0 ) - return; - - for ( unsigned i=0; i<all.size(); i++ ){ - WriteBackListener::waitFor( all[i] ); - } - } - virtual bool run(const string& dbName, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) { LastError *le = lastError.disableForCommand(); { @@ -859,110 +843,7 @@ namespace mongo { } ClientInfo * client = ClientInfo::get(); - set<string> * shards = client->getPrev(); - - if ( shards->size() == 0 ){ - result.appendNull( "err" ); - return true; - } - - //log() << "getlasterror enter: " << shards->size() << endl; - - - vector<OID> writebacks; - - // handle single server - if ( shards->size() == 1 ){ - string theShard = *(shards->begin() ); - result.append( "theshard" , theShard.c_str() ); - ShardConnection conn( theShard , "" ); - BSONObj res; - bool ok = conn->runCommand( dbName , cmdObj , res ); - //log() << "\t" << res << endl; - result.appendElements( res ); - conn.done(); - result.append( "singleShard" , theShard ); - addWriteBack( writebacks , res ); - - // hit other machines just to block - for ( set<string>::const_iterator i=client->sinceLastGetError().begin(); i!=client->sinceLastGetError().end(); ++i ){ - string temp = *i; - if ( temp == theShard ) - continue; - - ShardConnection conn( temp , "" ); - addWriteBack( writebacks , conn->getLastErrorDetailed() ); - conn.done(); - } - client->clearSinceLastGetError(); - handleWriteBacks( writebacks ); - return ok; - } - - BSONArrayBuilder bbb( result.subarrayStart( "shards" ) ); - - long long n = 0; - - // hit each shard - vector<string> errors; - vector<BSONObj> errorObjects; - for ( set<string>::iterator i = shards->begin(); i != shards->end(); i++ ){ - string theShard = *i; - bbb.append( theShard ); - ShardConnection conn( theShard , "" ); - BSONObj res; - bool ok = conn->runCommand( dbName , cmdObj , res ); - addWriteBack( writebacks, res ); - string temp = DBClientWithCommands::getLastErrorString( res ); - if ( ok == false || temp.size() ){ - errors.push_back( temp ); - errorObjects.push_back( res ); - } - n += res["n"].numberLong(); - conn.done(); - } - - bbb.done(); - - result.appendNumber( "n" , n ); - - // hit other machines just to block - for ( set<string>::const_iterator i=client->sinceLastGetError().begin(); i!=client->sinceLastGetError().end(); ++i ){ - string temp = *i; - if ( shards->count( temp ) ) - continue; - - ShardConnection conn( temp , "" ); - addWriteBack( writebacks, conn->getLastErrorDetailed() ); - conn.done(); - } - client->clearSinceLastGetError(); - - if ( errors.size() == 0 ){ - result.appendNull( "err" ); - handleWriteBacks( writebacks ); - return true; - } - - result.append( "err" , errors[0].c_str() ); - - { // errs - BSONArrayBuilder all( result.subarrayStart( "errs" ) ); - for ( unsigned i=0; i<errors.size(); i++ ){ - all.append( errors[i].c_str() ); - } - all.done(); - } - - { // errObjects - BSONArrayBuilder all( result.subarrayStart( "errObjects" ) ); - for ( unsigned i=0; i<errorObjects.size(); i++ ){ - all.append( errorObjects[i] ); - } - all.done(); - } - handleWriteBacks( writebacks ); - return true; + return client->getLastError( cmdObj , result ); } } cmdGetLastError; |