コード例 #1
0
void VoteRequester::Algorithm::processResponse(const RemoteCommandRequest& request,
                                               const ResponseStatus& response) {
    _responsesProcessed++;
    if (!response.isOK()) {  // failed response
        log() << "VoteRequester: Got failed response from " << request.target << ": "
              << response.getStatus();
    } else {
        _responders.insert(request.target);
        ReplSetRequestVotesResponse voteResponse;
        const auto status = voteResponse.initialize(response.getValue().data);
        if (!status.isOK()) {
            log() << "VoteRequester: Got error processing response with status: " << status
                  << ", resp:" << response.getValue().data;
        }

        if (voteResponse.getVoteGranted()) {
            LOG(3) << "VoteRequester: Got yes vote from " << request.target
                   << ", resp:" << response.getValue().data;
            _votes++;
        } else {
            log() << "VoteRequester: Got no vote from " << request.target
                  << " because: " << voteResponse.getReason()
                  << ", resp:" << response.getValue().data;
        }

        if (voteResponse.getTerm() > _term) {
            _staleTerm = true;
        }
    }
}
コード例 #2
0
void FreshnessScanner::Algorithm::processResponse(const RemoteCommandRequest& request,
                                                  const ResponseStatus& response) {
    _responsesProcessed++;
    if (!response.isOK()) {  // failed response
        LOG(2) << "FreshnessScanner: Got failed response from " << request.target << ": "
               << response.getStatus();
    } else {
        BSONObj opTimesObj = response.getValue().data.getObjectField("optimes");
        OpTime lastOpTime;
        Status status = bsonExtractOpTimeField(opTimesObj, "appliedOpTime", &lastOpTime);
        if (!status.isOK()) {
            return;
        }

        int index = _rsConfig.findMemberIndexByHostAndPort(request.target);
        FreshnessInfo freshnessInfo{index, lastOpTime};

        auto cmp = [](const FreshnessInfo& a, const FreshnessInfo& b) {
            return a.opTime > b.opTime;
        };
        auto iter =
            std::upper_bound(_freshnessInfos.begin(), _freshnessInfos.end(), freshnessInfo, cmp);
        _freshnessInfos.insert(iter, freshnessInfo);
    }
}
コード例 #3
0
ファイル: vote_requester.cpp プロジェクト: Amosvista/mongo
    void VoteRequester::Algorithm::processResponse(
            const RemoteCommandRequest& request,
            const ResponseStatus& response) {
        _responsesProcessed++;
        if (!response.isOK()) { // failed response
            log() << "VoteRequester: Got failed response from " << request.target
                  << ": " << response.getStatus();
        }
        else {
            ReplSetRequestVotesResponse voteResponse;
            voteResponse.initialize(response.getValue().data);
            if (voteResponse.getVoteGranted()) {
                _votes++;
            }
            else {
                log() << "VoteRequester: Got no vote from " << request.target
                      << " because: " << voteResponse.getReason();
            }

            if (voteResponse.getTerm() > _term) {
                _staleTerm = true;
            }
        }

    }
コード例 #4
0
ファイル: elect_cmd_runner.cpp プロジェクト: Amosvista/mongo
    void ElectCmdRunner::Algorithm::processResponse(
            const RemoteCommandRequest& request,
            const ResponseStatus& response) {

        ++_actualResponses;

        if (response.isOK()) {
            BSONObj res = response.getValue().data;
            log() << "received " << res["vote"] << " votes from " << request.target;
            LOG(1) << "full elect res: " << res.toString();
            BSONElement vote(res["vote"]); 
            if (vote.type() != mongo::NumberInt) {
                error() << "wrong type for vote argument in replSetElect command: " << 
                    typeName(vote.type());
                _sufficientResponsesReceived = true;
                return;
            }

            _receivedVotes += vote._numberInt();
        }
        else {
            warning() << "elect command to " << request.target << " failed: " <<
                response.getStatus();
        }
    }
コード例 #5
0
void ElectionWinnerDeclarer::Algorithm::processResponse(const RemoteCommandRequest& request,
                                                        const ResponseStatus& response) {
    _responsesProcessed++;
    if (!response.isOK()) {  // failed response
        log() << "ElectionWinnerDeclarer: Got failed response from " << request.target << ": "
              << response.getStatus();
        return;
    }

    Status cmdResponseStatus = getStatusFromCommandResult(response.getValue().data);
    if (!cmdResponseStatus.isOK()) {  // disagreement response
        _failed = true;
        _status = cmdResponseStatus;
        log() << "ElectionWinnerDeclarer: Got error response from " << request.target
              << " with term: " << response.getValue().data["term"].Number()
              << " and error: " << cmdResponseStatus;
    }
}
コード例 #6
0
void NetworkInterfaceASIO::AsyncOp::finish(const ResponseStatus& status) {
    // We never hold the access lock when we call finish from NetworkInterfaceASIO.
    _transitionToState(AsyncOp::State::kFinished);

    LOG(2) << "Request " << _request.id << " finished with response: "
           << (status.getStatus().isOK() ? status.getValue().data.toString()
                                         : status.getStatus().toString());

    // Calling the completion handler may invalidate state in this op, so do it last.
    _onFinish(status);
}
コード例 #7
0
void NetworkInterfaceMock::scheduleResponse(NetworkOperationIterator noi,
                                            Date_t when,
                                            const ResponseStatus& response) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    invariant(_currentlyRunning == kNetworkThread);
    NetworkOperationIterator insertBefore = _scheduled.begin();
    while ((insertBefore != _scheduled.end()) && (insertBefore->getResponseDate() <= when)) {
        ++insertBefore;
    }

    // If no RemoteCommandResponse was returned (for example, on a simulated network error), then
    // do not attempt to run the metadata hook, since there is no returned metadata.
    if (_metadataHook && response.isOK()) {
        _metadataHook->readReplyMetadata(noi->getRequest().target, response.getValue().metadata);
    }

    noi->setResponse(when, response);
    _scheduled.splice(insertBefore, _processing, noi);
}
コード例 #8
0
    void FreshnessChecker::Algorithm::processResponse(
                    const ReplicationExecutor::RemoteCommandRequest& request,
                    const ResponseStatus& response) {
        ++_responsesProcessed;
        bool votingMember = _isVotingMember(request.target);

        Status status = Status::OK();

        if (!response.isOK() ||
            !((status = getStatusFromCommandResult(response.getValue().data)).isOK())) {
            if (votingMember) {
                ++_failedVoterResponses;
                if (hadTooManyFailedVoterResponses()) {
                    _abortReason = QuorumUnreachable;
                }
            }
            if (!response.isOK()) { // network/executor error
                LOG(2) << "FreshnessChecker: Got failed response from " << request.target;
            }
            else {                 // command error, like unauth
                LOG(2) << "FreshnessChecker: Got error response from " << request.target
                       << " :" << status;
            }
            return;
        }

        const BSONObj res = response.getValue().data;

        LOG(2) << "FreshnessChecker: Got response from " << request.target
               << " of " << res;

        if (res["fresher"].trueValue()) {
            log() << "not electing self, we are not freshest";
            _abortReason = FresherNodeFound;
            return;
        }

        if (res["opTime"].type() != mongo::Date) {
            error() << "wrong type for opTime argument in replSetFresh response: " <<
                typeName(res["opTime"].type());
            _abortReason = FresherNodeFound;
            return;
        }
        OpTime remoteTime(res["opTime"].date());
        if (remoteTime == _lastOpTimeApplied) {
            _abortReason = FreshnessTie;
        }
        if (remoteTime > _lastOpTimeApplied) {
            // something really wrong (rogue command?)
            _abortReason = FresherNodeFound;
            return;
        }

        if (res["veto"].trueValue()) {
            BSONElement msg = res["errmsg"];
            if (!msg.eoo()) {
                log() << "not electing self, " << request.target.toString() <<
                    " would veto with '" << msg << "'";
            }
            else {
                log() << "not electing self, " << request.target.toString() <<
                    " would veto";
            }
            _abortReason = FresherNodeFound;
            return;
        }
    }
コード例 #9
0
void QuorumChecker::_tabulateHeartbeatResponse(const RemoteCommandRequest& request,
                                               const ResponseStatus& response) {
    ++_numResponses;
    if (!response.isOK()) {
        warning() << "Failed to complete heartbeat request to " << request.target << "; "
                  << response.getStatus();
        _badResponses.push_back(std::make_pair(request.target, response.getStatus()));
        return;
    }

    BSONObj resBSON = response.getValue().data;
    ReplSetHeartbeatResponse hbResp;
    Status hbStatus = hbResp.initialize(resBSON, 0);

    if (hbStatus.code() == ErrorCodes::InconsistentReplicaSetNames) {
        std::string message = str::stream() << "Our set name did not match that of "
                                            << request.target.toString();
        _vetoStatus = Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, message);
        warning() << message;
        return;
    }

    if (!hbStatus.isOK() && hbStatus != ErrorCodes::InvalidReplicaSetConfig) {
        warning() << "Got error (" << hbStatus << ") response on heartbeat request to "
                  << request.target << "; " << hbResp;
        _badResponses.push_back(std::make_pair(request.target, hbStatus));
        return;
    }

    if (!hbResp.getReplicaSetName().empty()) {
        if (hbResp.getConfigVersion() >= _rsConfig->getConfigVersion()) {
            std::string message = str::stream()
                << "Our config version of " << _rsConfig->getConfigVersion()
                << " is no larger than the version on " << request.target.toString()
                << ", which is " << hbResp.getConfigVersion();
            _vetoStatus = Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, message);
            warning() << message;
            return;
        }
    }

    if (_rsConfig->hasReplicaSetId()) {
        StatusWith<rpc::ReplSetMetadata> replMetadata =
            rpc::ReplSetMetadata::readFromMetadata(response.getValue().metadata);
        if (replMetadata.isOK() && replMetadata.getValue().getReplicaSetId().isSet() &&
            _rsConfig->getReplicaSetId() != replMetadata.getValue().getReplicaSetId()) {
            std::string message = str::stream()
                << "Our replica set ID of " << _rsConfig->getReplicaSetId()
                << " did not match that of " << request.target.toString() << ", which is "
                << replMetadata.getValue().getReplicaSetId();
            _vetoStatus = Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, message);
            warning() << message;
        }
    }

    const bool isInitialConfig = _rsConfig->getConfigVersion() == 1;
    if (isInitialConfig && hbResp.hasData()) {
        std::string message = str::stream() << "'" << request.target.toString()
                                            << "' has data already, cannot initiate set.";
        _vetoStatus = Status(ErrorCodes::CannotInitializeNodeWithData, message);
        warning() << message;
        return;
    }

    for (int i = 0; i < _rsConfig->getNumMembers(); ++i) {
        const MemberConfig& memberConfig = _rsConfig->getMemberAt(i);
        if (memberConfig.getHostAndPort() != request.target) {
            continue;
        }
        if (memberConfig.isElectable()) {
            ++_numElectable;
        }
        if (memberConfig.isVoter()) {
            _voters.push_back(request.target);
        }
        return;
    }
    invariant(false);
}