void ReplicationCoordinatorImpl::_handleHeartbeatResponse(
            const ReplicationExecutor::RemoteCommandCallbackData& cbData) {

        // remove handle from queued heartbeats
        _untrackHeartbeatHandle(cbData.myHandle);

        // Parse and validate the response.  At the end of this step, if responseStatus is OK then
        // hbResponse is valid.
        Status responseStatus = cbData.response.getStatus();
        if (responseStatus == ErrorCodes::CallbackCanceled) {
            return;
        }

        const HostAndPort& target = cbData.request.target;
        ReplSetHeartbeatResponse hbResponse;
        BSONObj resp;
        if (responseStatus.isOK()) {
            resp = cbData.response.getValue().data;
            responseStatus = getStatusFromCommandResult(resp);
        }
        if (responseStatus.isOK()) {
            responseStatus = hbResponse.initialize(resp);
        }
        if (!responseStatus.isOK()) {
            LOG(1) << "Error in heartbeat request to " << target << ";" << responseStatus;
            if (!resp.isEmpty()) {
                LOG(3) << "heartbeat response: " << resp;
            }
        }
        const Date_t now = _replExecutor.now();
        const OpTime lastApplied = _getLastOpApplied();  // Locks and unlocks _mutex.
        Milliseconds networkTime(0);
        StatusWith<ReplSetHeartbeatResponse> hbStatusResponse(hbResponse);
        if (cbData.response.isOK()) {
            networkTime = cbData.response.getValue().elapsedMillis;
        }
        else {
            hbStatusResponse = StatusWith<ReplSetHeartbeatResponse>(responseStatus);
        }
        HeartbeatResponseAction action =
            _topCoord->processHeartbeatResponse(
                    now,
                    networkTime,
                    target,
                    hbStatusResponse,
                    lastApplied);

        _scheduleHeartbeatToTarget(
                target,
                std::max(now, action.getNextHeartbeatStartDate()));

        _handleHeartbeatResponseAction(action, hbStatusResponse);
    }
Пример #2
0
 Status ReplicationCoordinatorImpl::processReplSetGetStatus(BSONObjBuilder* response) {
     Status result(ErrorCodes::InternalError, "didn't set status in prepareStatusResponse");
     CBHStatus cbh = _replExecutor->scheduleWork(
         stdx::bind(&TopologyCoordinator::prepareStatusResponse,
                    _topCoord.get(),
                    stdx::placeholders::_1,
                    Date_t(curTimeMillis64()),
                    time(0) - serverGlobalParams.started,
                    _getLastOpApplied(),
                    response,
                    &result));
     if (cbh.getStatus() == ErrorCodes::ShutdownInProgress) {
         return Status(ErrorCodes::ShutdownInProgress, "replication shutdown in progress");
     }
     fassert(18640, cbh.getStatus());
     _replExecutor->wait(cbh.getValue());
     return result;
 }
Пример #3
0
 Status ReplicationCoordinatorImpl::processHeartbeat(const ReplSetHeartbeatArgs& args,
                                                     ReplSetHeartbeatResponse* response) {
     Status result(ErrorCodes::InternalError, "didn't set status in prepareHeartbeatResponse");
     CBHStatus cbh = _replExecutor->scheduleWork(
         stdx::bind(&TopologyCoordinator::prepareHeartbeatResponse,
                    _topCoord.get(),
                    stdx::placeholders::_1,
                    Date_t(curTimeMillis64()),
                    args,
                    _settings.ourSetName(),
                    _getLastOpApplied(),
                    response,
                    &result));
     if (cbh.getStatus() == ErrorCodes::ShutdownInProgress) {
         return Status(ErrorCodes::ShutdownInProgress, "replication shutdown in progress");
     }
     fassert(18508, cbh.getStatus());
     _replExecutor->wait(cbh.getValue());
     return result;
 }