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