Exemplo n.º 1
0
    // 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();
            }
        }

    }