bool SyncSourceFeedback::_connect(const std::string& hostName) { if (hasConnection()) { return true; } log() << "replset setting syncSourceFeedback to " << hostName << rsLog; _connection.reset(new DBClientConnection(false, 0, OplogReader::tcp_timeout)); string errmsg; try { if (!_connection->connect(hostName.c_str(), errmsg) || (getGlobalAuthorizationManager()->isAuthEnabled() && !replAuthenticate())) { resetConnection(); log() << "repl: " << errmsg << endl; return false; } } catch (const DBException& e) { log() << "Error connecting to " << hostName << ": " << e.what(); resetConnection(); return false; } if (!replHandshake()) { if (!supportsUpdater()) { return connectOplogReader(hostName); } return false; } return true; }
bool SyncSourceFeedback::connect(const Member* target) { boost::unique_lock<boost::mutex> lock(_connmtx); resetConnection(); resetOplogReaderConnection(); _syncTarget = target; if (_connect(target->fullName())) { if (!supportsUpdater()) { return true; } } return false; }
void SyncSourceFeedback::run() { Client::initThread("SyncSourceFeedbackThread"); while (true) { { boost::unique_lock<boost::mutex> lock(_mtx); while (!_positionChanged && !_handshakeNeeded) { _cond.wait(lock); } boost::unique_lock<boost::mutex> conlock(_connmtx); const Member* target = replset::BackgroundSync::get()->getSyncTarget(); if (_syncTarget != target) { resetConnection(); _syncTarget = target; } if (!hasConnection()) { // fix connection if need be if (!target) { continue; } if (!_connect(target->fullName())) { continue; } else if (!supportsUpdater()) { _handshakeNeeded = false; _positionChanged = false; continue; } } if (_handshakeNeeded) { if (!replHandshake()) { _handshakeNeeded = true; continue; } else { _handshakeNeeded = false; } } if (_positionChanged) { if (!updateUpstream()) { _positionChanged = true; continue; } else { _positionChanged = false; } } } } }
void SyncSourceFeedback::percolate(const mongo::OID& rid, const OpTime& ot) { // Update our own record of where this node is, and then register an upstream // message about this. // Note that we must keep the map up to date even if we are not actively reporting // upstream via the new command, since our sync source might later change to a node // that does support the command. updateMap(rid, ot); if (!supportsUpdater()) { // this is only necessary if our sync source does not support // the new syncSourceFeedback command theReplSet->ghost->send(boost::bind(&GhostSync::percolate, theReplSet->ghost, rid, ot)); } }
bool SyncSourceFeedback::_connect(const std::string& hostName) { if (hasConnection()) { return true; } _connection.reset(new DBClientConnection(false, 0, OplogReader::tcp_timeout)); string errmsg; if (!_connection->connect(hostName.c_str(), errmsg) || (AuthorizationManager::isAuthEnabled() && !replAuthenticate(true))) { resetConnection(); log() << "repl: " << errmsg << endl; return false; } if (!replHandshake()) { if (!supportsUpdater()) { return connectOplogReader(hostName); } return false; } return true; }
void SyncSourceFeedback::run() { Client::initThread("SyncSourceFeedbackThread"); bool sleepNeeded = false; while (true) { if (sleepNeeded) { sleepmillis(500); sleepNeeded = false; } { boost::unique_lock<boost::mutex> lock(_mtx); while (!_positionChanged && !_handshakeNeeded) { _cond.wait(lock); } if (theReplSet->isPrimary()) { _positionChanged = false; _handshakeNeeded = false; continue; } const Member* target = replset::BackgroundSync::get()->getSyncTarget(); boost::unique_lock<boost::mutex> connlock(_connmtx); if (_syncTarget != target) { resetConnection(); _syncTarget = target; } if (!hasConnection()) { // fix connection if need be if (!target) { sleepNeeded = true; continue; } if (!_connect(target->fullName())) { sleepNeeded = true; continue; } else if (!supportsUpdater()) { _handshakeNeeded = false; _positionChanged = false; continue; } } if (_handshakeNeeded) { if (!replHandshake()) { _handshakeNeeded = true; continue; } else { _handshakeNeeded = false; _positionChanged = true; } } if (_positionChanged) { if (!updateUpstream()) { // no need to set _handshakeNeeded to true as a failed updateUpstream() call // will call resetConnection() and when the new connection is established // the handshake process will be run _positionChanged = true; continue; } else { _positionChanged = false; } } } } }