void SyncSourceFeedback::run() {
        Client::initThread("SyncSourceFeedbackThread");
        OperationContextImpl txn;

        bool positionChanged = false;
        bool handshakeNeeded = false;
        ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator();
        while (!inShutdown()) { // TODO(spencer): Remove once legacy repl coordinator is gone.
            {
                boost::unique_lock<boost::mutex> lock(_mtx);
                while (!_positionChanged && !_handshakeNeeded && !_shutdownSignaled) {
                    _cond.wait(lock);
                }

                if (_shutdownSignaled) {
                    break;
                }

                positionChanged = _positionChanged;
                handshakeNeeded = _handshakeNeeded;
                _positionChanged = false;
                _handshakeNeeded = false;
            }

            MemberState state = replCoord->getCurrentMemberState();
            if (state.primary() || state.fatal() || state.startup()) {
                continue;
            }
            const Member* target = BackgroundSync::get()->getSyncTarget();
            if (_syncTarget != target) {
                _resetConnection();
                _syncTarget = target;
            }
            if (!hasConnection()) {
                // fix connection if need be
                if (!target) {
                    sleepmillis(500);
                    continue;
                }
                if (!_connect(&txn, target->fullName())) {
                    sleepmillis(500);
                    continue;
                }
            }
            if (handshakeNeeded) {
                if (!replHandshake(&txn)) {
                    boost::unique_lock<boost::mutex> lock(_mtx);
                    _handshakeNeeded = true;
                    continue;
                }
            }
            if (positionChanged) {
                if (!updateUpstream(&txn)) {
                    boost::unique_lock<boost::mutex> lock(_mtx);
                    _positionChanged = true;
                }
            }
        }
        cc().shutdown();
    }
Esempio n. 2
0
void SyncSourceFeedback::run() {
    Client::initThread("SyncSourceFeedback");

    ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator();
    while (true) {  // breaks once _shutdownSignaled is true
        {
            stdx::unique_lock<stdx::mutex> lock(_mtx);
            while (!_positionChanged && !_shutdownSignaled) {
                if (_cond.wait_for(lock, _keepAliveInterval) == stdx::cv_status::timeout) {
                    break;
                }
            }

            if (_shutdownSignaled) {
                break;
            }

            _positionChanged = false;
        }

        auto txn = cc().makeOperationContext();
        MemberState state = replCoord->getMemberState();
        if (state.primary() || state.startup()) {
            _resetConnection();
            continue;
        }
        const HostAndPort target = BackgroundSync::get()->getSyncTarget();
        if (_syncTarget != target) {
            _resetConnection();
            _syncTarget = target;
        }
        if (!hasConnection()) {
            // fix connection if need be
            if (target.empty()) {
                sleepmillis(500);
                stdx::unique_lock<stdx::mutex> lock(_mtx);
                _positionChanged = true;
                continue;
            }
            if (!_connect(txn.get(), target)) {
                sleepmillis(500);
                stdx::unique_lock<stdx::mutex> lock(_mtx);
                _positionChanged = true;
                continue;
            }
        }
        Status status = updateUpstream(txn.get());
        if (!status.isOK()) {
            sleepmillis(500);
            stdx::unique_lock<stdx::mutex> lock(_mtx);
            _positionChanged = true;
        }
    }
}
 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::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;
                 }
             }
         }
     }
 }