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 /s/client.cpp | |
parent | 54ebaf04cc49e585f5144e4ad7044f69b2afa72f (diff) | |
download | mongo-224a70df915283c9ad2f64b31556875497fdfba8.tar.gz |
move getLastError code to client.cpp so can access not only through command interface
Diffstat (limited to 's/client.cpp')
-rw-r--r-- | s/client.cpp | 152 |
1 files changed, 137 insertions, 15 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; |