summaryrefslogtreecommitdiff
path: root/client/dbclient_rs.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2011-12-15 10:02:19 +0100
committerAntonin Kral <a.kral@bobek.cz>2011-12-15 10:02:46 +0100
commit0b48f8ada2acb0de830b23f8cefc8e3fea28d915 (patch)
treef7c2811269b6b53199412be2dd5ec02eea15d55d /client/dbclient_rs.cpp
parent85f1cd56145b90a32b7ccdc750000deeed54fe22 (diff)
parentf0d9a01bccdaeb466c12c92057914bbfef59526c (diff)
downloadmongodb-0b48f8ada2acb0de830b23f8cefc8e3fea28d915.tar.gz
Merge branch 'upstream/2.0.2'
Diffstat (limited to 'client/dbclient_rs.cpp')
-rw-r--r--client/dbclient_rs.cpp66
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;
}
}