summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2010-12-27 16:44:15 -0500
committerEliot Horowitz <eliot@10gen.com>2010-12-27 16:44:15 -0500
commit224a70df915283c9ad2f64b31556875497fdfba8 (patch)
tree3acba3e12b24274cc17ef16753b2d4dcc0391a7a
parent54ebaf04cc49e585f5144e4ad7044f69b2afa72f (diff)
downloadmongo-224a70df915283c9ad2f64b31556875497fdfba8.tar.gz
move getLastError code to client.cpp so can access not only through command interface
-rw-r--r--s/client.cpp152
-rw-r--r--s/client.h17
-rw-r--r--s/commands_admin.cpp121
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;