DBClientConnection * DBClientReplicaSet::checkMaster() { ReplicaSetMonitorPtr monitor = _getMonitor(); HostAndPort h = monitor->getMasterOrUassert(); if ( h == _masterHost && _master ) { // a master is selected. let's just make sure connection didn't die if ( ! _master->isFailed() ) return _master.get(); monitor->failedHost( _masterHost ); h = monitor->getMasterOrUassert(); // old master failed, try again. } _masterHost = h; ConnectionString connStr(_masterHost); string errmsg; DBClientConnection* newConn = NULL; try { // Needs to perform a dynamic_cast because we need to set the replSet // callback. We should eventually not need this after we remove the // callback. newConn = dynamic_cast<DBClientConnection*>( connStr.connect(errmsg, _so_timeout)); } catch (const AssertionException& ex) { errmsg = ex.toString(); } if (newConn == NULL || !errmsg.empty()) { monitor->failedHost(_masterHost); uasserted(13639, str::stream() << "can't connect to new replica set master [" << _masterHost.toString() << "]" << (errmsg.empty()? "" : ", err: ") << errmsg); } _master.reset(newConn); _master->setReplSetClientCallback(this); _master->setRunCommandHook(_runCommandHook); _master->setPostRunCommandHook(_postRunCommandHook); _auth( _master.get() ); return _master.get(); }
Status DBClientShardResolver::findMaster( const std::string connString, ConnectionString* resolvedHost ) { std::string errMsg; ConnectionString rawHost = ConnectionString::parse( connString, errMsg ); dassert( errMsg == "" ); dassert( rawHost.type() == ConnectionString::SET || rawHost.type() == ConnectionString::MASTER ); if ( rawHost.type() == ConnectionString::MASTER ) { *resolvedHost = rawHost; return Status::OK(); } // // If we need to, then get the particular node we're targeting in the replica set // // Don't create the monitor unless we need to - fast path ReplicaSetMonitorPtr replMonitor = ReplicaSetMonitor::get(rawHost.getSetName()); if (!replMonitor) { // Slow path std::set<HostAndPort> seedServers(rawHost.getServers().begin(), rawHost.getServers().end()); ReplicaSetMonitor::createIfNeeded(rawHost.getSetName(), seedServers); replMonitor = ReplicaSetMonitor::get(rawHost.getSetName()); } if (!replMonitor) { return Status( ErrorCodes::ReplicaSetNotFound, string("unknown replica set ") + rawHost.getSetName() ); } try { // This can throw when we don't find a master! HostAndPort masterHostAndPort = replMonitor->getMasterOrUassert(); *resolvedHost = ConnectionString::parse( masterHostAndPort.toString(), errMsg ); dassert( errMsg == "" ); return Status::OK(); } catch ( const DBException& ) { return Status( ErrorCodes::HostNotFound, string("could not contact primary for replica set ") + replMonitor->getName() ); } // Unreachable dassert( false ); return Status( ErrorCodes::UnknownError, "" ); }
Status DBClientShardResolver::findMaster( const std::string connString, ConnectionString* resolvedHost ) { std::string errMsg; ConnectionString rawHost = ConnectionString::parse( connString, errMsg ); dassert( errMsg == "" ); dassert( rawHost.type() == ConnectionString::SET || rawHost.type() == ConnectionString::MASTER ); if ( rawHost.type() == ConnectionString::MASTER ) { *resolvedHost = rawHost; return Status::OK(); } // // If we need to, then get the particular node we're targeting in the replica set // // Does not reload the monitor if it doesn't currently exist ReplicaSetMonitorPtr replMonitor = ReplicaSetMonitor::get( rawHost.getSetName(), false ); if ( !replMonitor ) { return Status( ErrorCodes::ReplicaSetNotFound, string("unknown replica set ") + rawHost.getSetName() ); } try { // This can throw when we don't find a master! HostAndPort masterHostAndPort = replMonitor->getMasterOrUassert(); *resolvedHost = ConnectionString::parse( masterHostAndPort.toString( true ), errMsg ); dassert( errMsg == "" ); return Status::OK(); } catch ( const DBException& ) { return Status( ErrorCodes::HostNotFound, string("could not contact primary for replica set ") + replMonitor->getName() ); } // Unreachable dassert( false ); return Status( ErrorCodes::UnknownError, "" ); }