diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-12-15 10:02:19 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-12-15 10:02:46 +0100 |
commit | 0b48f8ada2acb0de830b23f8cefc8e3fea28d915 (patch) | |
tree | f7c2811269b6b53199412be2dd5ec02eea15d55d /client/dbclient_rs.cpp | |
parent | 85f1cd56145b90a32b7ccdc750000deeed54fe22 (diff) | |
parent | f0d9a01bccdaeb466c12c92057914bbfef59526c (diff) | |
download | mongodb-0b48f8ada2acb0de830b23f8cefc8e3fea28d915.tar.gz |
Merge branch 'upstream/2.0.2'
Diffstat (limited to 'client/dbclient_rs.cpp')
-rw-r--r-- | client/dbclient_rs.cpp | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/client/dbclient_rs.cpp b/client/dbclient_rs.cpp index 2cab1f7..c57a52d 100644 --- a/client/dbclient_rs.cpp +++ b/client/dbclient_rs.cpp @@ -247,38 +247,27 @@ namespace mongo { } HostAndPort ReplicaSetMonitor::getSlave() { + LOG(2) << "dbclient_rs getSlave " << getServerAddress() << endl; - LOG(2) << "selecting new slave from replica set " << getServerAddress() << endl; - - // Logic is to retry three times for any secondary node, if we can't find any secondary, we'll take - // any "ok" node - // TODO: Could this query hidden nodes? - const int MAX = 3; - for ( int xxx=0; xxx<MAX; xxx++ ) { + scoped_lock lk( _lock ); - { - scoped_lock lk( _lock ); - - unsigned i = 0; - for ( ; i<_nodes.size(); i++ ) { - _nextSlave = ( _nextSlave + 1 ) % _nodes.size(); - if ( _nextSlave == _master ){ - LOG(2) << "not selecting " << _nodes[_nextSlave] << " as it is the current master" << endl; - continue; - } - if ( _nodes[ _nextSlave ].okForSecondaryQueries() || ( _nodes[ _nextSlave ].ok && ( xxx + 1 ) >= MAX ) ) - return _nodes[ _nextSlave ].addr; - - LOG(2) << "not selecting " << _nodes[_nextSlave] << " as it is not ok to use" << endl; - } - + for ( unsigned ii = 0; ii < _nodes.size(); ii++ ) { + _nextSlave = ( _nextSlave + 1 ) % _nodes.size(); + if ( _nextSlave != _master ) { + if ( _nodes[ _nextSlave ].okForSecondaryQueries() ) + return _nodes[ _nextSlave ].addr; + LOG(2) << "dbclient_rs getSlave not selecting " << _nodes[_nextSlave] << ", not currently okForSecondaryQueries" << endl; } + } - check(false); + if( _master >= 0 ) { + assert( static_cast<unsigned>(_master) < _nodes.size() ); + LOG(2) << "dbclient_rs getSlave no member in secondary state found, returning primary " << _nodes[ _master ] << endl; + return _nodes[_master].addr; } - LOG(2) << "no suitable slave nodes found, returning default node " << _nodes[ 0 ] << endl; - + LOG(2) << "dbclient_rs getSlave no suitable member found, returning first node " << _nodes[ 0 ] << endl; + assert( _nodes.size() > 0 ); return _nodes[0].addr; } @@ -820,10 +809,14 @@ namespace mongo { 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; + if ( qm.queryOptions & QueryOption_SlaveOk ) { for ( int i=0; i<3; i++ ) { try { @@ -844,7 +837,26 @@ namespace mongo { DBClientConnection* m = checkMaster(); if ( actualServer ) *actualServer = m->getServerAddress(); - return m->call( toSend , response , assertOk ); + + 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; } } |