inline bool DBClientConnection::runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info, int options) { if ( DBClientWithCommands::runCommand( dbname , cmd , info , options ) ) return true; if ( clientSet && isNotMasterErrorString( info["errmsg"] ) ) { clientSet->isntMaster(); // At this point, we've probably deleted *this* object, do *not* use afterward } return false; }
void DBClientConnection::checkResponse( const char *data, int nReturned, bool* retry, string* host ) { /* check for errors. the only one we really care about at * this stage is "not master" */ *retry = false; *host = _serverString; if ( clientSet && nReturned ) { assert(data); BSONObj o(data); if ( isNotMasterErrorString( getErrField(o) ) ) { clientSet->isntMaster(); } } }
bool DBClientReplicaSet::call(Message &toSend, Message &response, bool assertOk, string * actualServer) { const char * ns = 0; if (toSend.operation() == dbQuery) { // TODO: might be possible to do this faster by changing api DbMessage dm(toSend); QueryMessage qm(dm); ns = qm.ns; shared_ptr<ReadPreferenceSetting> readPref( _extractReadPref( qm.query, qm.queryOptions ) ); if ( _isSecondaryQuery( ns, qm.query, *readPref ) ) { LOG( 3 ) << "dbclient_rs call using secondary or tagged node selection in " << _getMonitor()->getName() << ", read pref is " << readPref->toBSON() << " (primary : " << ( _master.get() != NULL ? _master->getServerAddress() : "[not cached]" ) << ", lastTagged : " << ( _lastSlaveOkConn.get() != NULL ? _lastSlaveOkConn->getServerAddress() : "[not cached]" ) << ")" << endl; for (size_t retry = 0; retry < MAX_RETRY; retry++) { try { DBClientConnection* conn = selectNodeUsingTags(readPref); if (conn == NULL) { return false; } if (actualServer != NULL) { *actualServer = conn->getServerAddress(); } return conn->call(toSend, response, assertOk); } catch ( const DBException& dbExcep ) { LOG(1) << "can't call replica set node " << _lastSlaveOkHost << ": " << causedBy( dbExcep ) << endl; if ( actualServer ) *actualServer = ""; invalidateLastSlaveOkCache(); } } // Was not able to successfully send after max retries return false; } } LOG( 3 ) << "dbclient_rs call to primary node in " << _getMonitor()->getName() << endl; DBClientConnection* m = checkMaster(); if ( actualServer ) *actualServer = m->getServerAddress(); if ( ! m->call( toSend , response , assertOk ) ) return false; if ( ns ) { QueryResult * res = (QueryResult*)response.singleData(); if ( res->nReturned == 1 ) { BSONObj x(res->data() ); if ( str::contains( ns , "$cmd" ) ) { if ( isNotMasterErrorString( x["errmsg"] ) ) isntMaster(); } else { if ( isNotMasterErrorString( getErrField( x ) ) ) isntMaster(); } } } return true; }