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; } } }
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); } }
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; } } }
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(); } }
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; } }
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); }
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); }
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; } }
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); }