// Produce a reply to a RAFT-style RequestVote RPC; this is MongoDB ReplSetFresh command // The caller should validate that the message is for the correct set, and has the required data void TopologyCoordinatorImpl::prepareRequestVoteResponse(const Date_t now, const BSONObj& cmdObj, const OpTime& lastOpApplied, std::string& errmsg, BSONObjBuilder& result) { string who = cmdObj["who"].String(); int cfgver = cmdObj["cfgver"].Int(); OpTime opTime(cmdObj["opTime"].Date()); bool weAreFresher = false; if( _currentConfig.getConfigVersion() > cfgver ) { log() << "replSet member " << who << " is not yet aware its cfg version " << cfgver << " is stale"; result.append("info", "config version stale"); weAreFresher = true; } // check not only our own optime, but any other member we can reach else if( opTime < _commitOkayThrough || opTime < _latestKnownOpTime()) { weAreFresher = true; } result.appendDate("opTime", lastOpApplied.asDate()); result.append("fresher", weAreFresher); bool doVeto = _shouldVeto(cmdObj, errmsg); result.append("veto",doVeto); if (doVeto) { result.append("errmsg", errmsg); } }
void ReplSetHeartbeatResponse::addToBSON(BSONObjBuilder* builder) const { if (_mismatch) { *builder << kOkFieldName << 0.0; *builder << kMismatchFieldName << _mismatch; return; } builder->append(kOkFieldName, 1.0); if (_timeSet) { *builder << kTimeFieldName << durationCount<Seconds>(_time); } if (_electionTimeSet) { builder->appendDate(kElectionTimeFieldName, Date_t::fromMillisSinceEpoch(_electionTime.asLL())); } if (_configSet) { *builder << kConfigFieldName << _config.toBSON(); } if (_electableSet) { *builder << kIsElectableFieldName << _electable; } if (_isReplSet) { *builder << "rs" << _isReplSet; } if (_stateDisagreement) { *builder << kHasStateDisagreementFieldName << _stateDisagreement; } if (_stateSet) { builder->appendIntOrLL(kMemberStateFieldName, _state.s); } if (_configVersion != -1) { *builder << kConfigVersionFieldName << _configVersion; } *builder << kHbMessageFieldName << _hbmsg; if (!_setName.empty()) { *builder << kReplSetFieldName << _setName; } if (!_syncingTo.empty()) { *builder << kSyncSourceFieldName << _syncingTo.toString(); } if (_hasDataSet) { builder->append(kHasDataFieldName, _hasData); } if (_term != -1) { builder->append(kTermFieldName, _term); } if (_primaryIdSet) { builder->append(kPrimaryIdFieldName, _primaryId); } if (_opTimeSet) { if (_protocolVersion == 0) { builder->appendDate(kOpTimeFieldName, Date_t::fromMillisSinceEpoch(_opTime.getTimestamp().asLL())); } else { BSONObjBuilder opTime(builder->subobjStart(kOpTimeFieldName)); opTime.append(kTimestampFieldName, _opTime.getTimestamp()); opTime.append(kTermFieldName, _opTime.getTerm()); opTime.done(); } } }