Search in sources :

Example 36 with LogId

use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.

the class RocksDBLogStorage method load.

private void load(final ConfigurationManager confManager) {
    checkState();
    try (final RocksIterator it = this.db.newIterator(this.confHandle, this.totalOrderReadOptions)) {
        it.seekToFirst();
        while (it.isValid()) {
            final byte[] ks = it.key();
            final byte[] bs = it.value();
            // LogEntry index
            if (ks.length == 8) {
                final LogEntry entry = this.logEntryDecoder.decode(bs);
                if (entry != null) {
                    if (entry.getType() == EntryType.ENTRY_TYPE_CONFIGURATION) {
                        final ConfigurationEntry confEntry = new ConfigurationEntry();
                        confEntry.setId(new LogId(entry.getId().getIndex(), entry.getId().getTerm()));
                        confEntry.setConf(new Configuration(entry.getPeers(), entry.getLearners()));
                        if (entry.getOldPeers() != null) {
                            confEntry.setOldConf(new Configuration(entry.getOldPeers(), entry.getOldLearners()));
                        }
                        if (confManager != null) {
                            confManager.add(confEntry);
                        }
                    }
                } else {
                    LOG.warn("Fail to decode conf entry at index {}, the log data is: {}.", Bits.getLong(ks, 0), BytesUtil.toHex(bs));
                }
            } else {
                if (Arrays.equals(FIRST_LOG_IDX_KEY, ks)) {
                    setFirstLogIndex(Bits.getLong(bs, 0));
                    truncatePrefixInBackground(0L, this.firstLogIndex);
                } else {
                    LOG.warn("Unknown entry in configuration storage key={}, value={}.", BytesUtil.toHex(ks), BytesUtil.toHex(bs));
                }
            }
            it.next();
        }
    }
}
Also used : Configuration(com.alipay.sofa.jraft.conf.Configuration) RocksIterator(org.rocksdb.RocksIterator) ConfigurationEntry(com.alipay.sofa.jraft.conf.ConfigurationEntry) LogId(com.alipay.sofa.jraft.entity.LogId) LogEntry(com.alipay.sofa.jraft.entity.LogEntry)

Example 37 with LogId

use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.

the class V1Encoder method encode.

@Override
public byte[] encode(final LogEntry log) {
    if (log.hasLearners()) {
        throw new IllegalArgumentException("V1 log entry encoder doesn't support learners");
    }
    EntryType type = log.getType();
    LogId id = log.getId();
    List<PeerId> peers = log.getPeers();
    List<PeerId> oldPeers = log.getOldPeers();
    ByteBuffer data = log.getData();
    // magic number 1 byte
    int totalLen = 1;
    final int iType = type.getNumber();
    final long index = id.getIndex();
    final long term = id.getTerm();
    // type(4) + index(8) + term(8)
    totalLen += 4 + 8 + 8;
    int peerCount = 0;
    // peer count
    totalLen += 4;
    final List<String> peerStrs = new ArrayList<>(peerCount);
    if (peers != null) {
        peerCount = peers.size();
        for (final PeerId peer : peers) {
            final String peerStr = peer.toString();
            // peer len (short in 2 bytes)
            // peer str
            totalLen += 2 + peerStr.length();
            peerStrs.add(peerStr);
        }
    }
    int oldPeerCount = 0;
    // old peer count
    totalLen += 4;
    final List<String> oldPeerStrs = new ArrayList<>(oldPeerCount);
    if (oldPeers != null) {
        oldPeerCount = oldPeers.size();
        for (final PeerId peer : oldPeers) {
            final String peerStr = peer.toString();
            // peer len (short in 2 bytes)
            // peer str
            totalLen += 2 + peerStr.length();
            oldPeerStrs.add(peerStr);
        }
    }
    final int bodyLen = data != null ? data.remaining() : 0;
    totalLen += bodyLen;
    final byte[] content = new byte[totalLen];
    // {0} magic
    content[0] = LogEntryV1CodecFactory.MAGIC;
    // 1-5 type
    Bits.putInt(content, 1, iType);
    // 5-13 index
    Bits.putLong(content, 5, index);
    // 13-21 term
    Bits.putLong(content, 13, term);
    // peers
    // 21-25 peer count
    Bits.putInt(content, 21, peerCount);
    int pos = 25;
    for (final String peerStr : peerStrs) {
        final byte[] ps = AsciiStringUtil.unsafeEncode(peerStr);
        Bits.putShort(content, pos, (short) peerStr.length());
        System.arraycopy(ps, 0, content, pos + 2, ps.length);
        pos += 2 + ps.length;
    }
    // old peers
    // old peers count
    Bits.putInt(content, pos, oldPeerCount);
    pos += 4;
    for (final String peerStr : oldPeerStrs) {
        final byte[] ps = AsciiStringUtil.unsafeEncode(peerStr);
        Bits.putShort(content, pos, (short) peerStr.length());
        System.arraycopy(ps, 0, content, pos + 2, ps.length);
        pos += 2 + ps.length;
    }
    // data
    if (data != null) {
        System.arraycopy(data.array(), data.position(), content, pos, data.remaining());
    }
    return content;
}
Also used : EntryType(com.alipay.sofa.jraft.entity.EnumOutter.EntryType) ArrayList(java.util.ArrayList) LogId(com.alipay.sofa.jraft.entity.LogId) ByteBuffer(java.nio.ByteBuffer) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 38 with LogId

use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.

the class V2Encoder method encode.

@Override
public byte[] encode(final LogEntry log) {
    Requires.requireNonNull(log, "Null log");
    final LogId logId = log.getId();
    final PBLogEntry.Builder builder = // 
    PBLogEntry.newBuilder().setType(// 
    log.getType()).setIndex(// 
    logId.getIndex()).setTerm(logId.getTerm());
    final List<PeerId> peers = log.getPeers();
    if (hasPeers(peers)) {
        encodePeers(builder, peers);
    }
    final List<PeerId> oldPeers = log.getOldPeers();
    if (hasPeers(oldPeers)) {
        encodeOldPeers(builder, oldPeers);
    }
    final List<PeerId> learners = log.getLearners();
    if (hasPeers(learners)) {
        encodeLearners(builder, learners);
    }
    final List<PeerId> oldLearners = log.getOldLearners();
    if (hasPeers(oldLearners)) {
        encodeOldLearners(builder, oldLearners);
    }
    if (log.hasChecksum()) {
        builder.setChecksum(log.getChecksum());
    }
    builder.setData(log.getData() != null ? ZeroByteStringHelper.wrap(log.getData()) : ByteString.EMPTY);
    final PBLogEntry pbLogEntry = builder.build();
    final int bodyLen = pbLogEntry.getSerializedSize();
    final byte[] ret = new byte[LogEntryV2CodecFactory.HEADER_SIZE + bodyLen];
    // write header
    int i = 0;
    for (; i < LogEntryV2CodecFactory.MAGIC_BYTES.length; i++) {
        ret[i] = LogEntryV2CodecFactory.MAGIC_BYTES[i];
    }
    ret[i++] = LogEntryV2CodecFactory.VERSION;
    // avoid memory copy for only 3 bytes
    for (; i < LogEntryV2CodecFactory.HEADER_SIZE; i++) {
        ret[i] = LogEntryV2CodecFactory.RESERVED[i - LogEntryV2CodecFactory.MAGIC_BYTES.length - 1];
    }
    // write body
    writeToByteArray(pbLogEntry, ret, i, bodyLen);
    return ret;
}
Also used : PBLogEntry(com.alipay.sofa.jraft.entity.codec.v2.LogOutter.PBLogEntry) LogId(com.alipay.sofa.jraft.entity.LogId) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Example 39 with LogId

use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.

the class TestUtils method mockEntry.

public static LogEntry mockEntry(final int index, final int term, final int dataSize) {
    LogEntry entry = new LogEntry(EnumOutter.EntryType.ENTRY_TYPE_NO_OP);
    entry.setId(new LogId(index, term));
    if (dataSize > 0) {
        byte[] bs = new byte[dataSize];
        ThreadLocalRandom.current().nextBytes(bs);
        entry.setData(ByteBuffer.wrap(bs));
    }
    return entry;
}
Also used : LogId(com.alipay.sofa.jraft.entity.LogId) LogEntry(com.alipay.sofa.jraft.entity.LogEntry)

Example 40 with LogId

use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.

the class NodeImpl method bootstrap.

public boolean bootstrap(final BootstrapOptions opts) throws InterruptedException {
    if (opts.getLastLogIndex() > 0 && (opts.getGroupConf().isEmpty() || opts.getFsm() == null)) {
        LOG.error("Invalid arguments for bootstrap, groupConf={}, fsm={}, lastLogIndex={}.", opts.getGroupConf(), opts.getFsm(), opts.getLastLogIndex());
        return false;
    }
    if (opts.getGroupConf().isEmpty()) {
        LOG.error("Bootstrapping an empty node makes no sense.");
        return false;
    }
    Requires.requireNonNull(opts.getServiceFactory(), "Null jraft service factory");
    this.serviceFactory = opts.getServiceFactory();
    // Term is not an option since changing it is very dangerous
    final long bootstrapLogTerm = opts.getLastLogIndex() > 0 ? 1 : 0;
    final LogId bootstrapId = new LogId(opts.getLastLogIndex(), bootstrapLogTerm);
    this.options = new NodeOptions();
    this.raftOptions = this.options.getRaftOptions();
    this.metrics = new NodeMetrics(opts.isEnableMetrics());
    this.options.setFsm(opts.getFsm());
    this.options.setLogUri(opts.getLogUri());
    this.options.setRaftMetaUri(opts.getRaftMetaUri());
    this.options.setSnapshotUri(opts.getSnapshotUri());
    this.configManager = new ConfigurationManager();
    // Create fsmCaller at first as logManager needs it to report error
    this.fsmCaller = new FSMCallerImpl();
    if (!initLogStorage()) {
        LOG.error("Fail to init log storage.");
        return false;
    }
    if (!initMetaStorage()) {
        LOG.error("Fail to init meta storage.");
        return false;
    }
    if (this.currTerm == 0) {
        this.currTerm = 1;
        if (!this.metaStorage.setTermAndVotedFor(1, new PeerId())) {
            LOG.error("Fail to set term.");
            return false;
        }
    }
    if (opts.getFsm() != null && !initFSMCaller(bootstrapId)) {
        LOG.error("Fail to init fsm caller.");
        return false;
    }
    final LogEntry entry = new LogEntry(EnumOutter.EntryType.ENTRY_TYPE_CONFIGURATION);
    entry.getId().setTerm(this.currTerm);
    entry.setPeers(opts.getGroupConf().listPeers());
    entry.setLearners(opts.getGroupConf().listLearners());
    final List<LogEntry> entries = new ArrayList<>();
    entries.add(entry);
    final BootstrapStableClosure bootstrapDone = new BootstrapStableClosure();
    this.logManager.appendEntries(entries, bootstrapDone);
    if (!bootstrapDone.await().isOk()) {
        LOG.error("Fail to append configuration.");
        return false;
    }
    if (opts.getLastLogIndex() > 0) {
        if (!initSnapshotStorage()) {
            LOG.error("Fail to init snapshot storage.");
            return false;
        }
        final SynchronizedClosure snapshotDone = new SynchronizedClosure();
        this.snapshotExecutor.doSnapshot(snapshotDone);
        if (!snapshotDone.await().isOk()) {
            LOG.error("Fail to save snapshot, status={}.", snapshotDone.getStatus());
            return false;
        }
    }
    if (this.logManager.getFirstLogIndex() != opts.getLastLogIndex() + 1) {
        throw new IllegalStateException("First and last log index mismatch");
    }
    if (opts.getLastLogIndex() > 0) {
        if (this.logManager.getLastLogIndex() != opts.getLastLogIndex()) {
            throw new IllegalStateException("Last log index mismatch");
        }
    } else {
        if (this.logManager.getLastLogIndex() != opts.getLastLogIndex() + 1) {
            throw new IllegalStateException("Last log index mismatch");
        }
    }
    return true;
}
Also used : SynchronizedClosure(com.alipay.sofa.jraft.closure.SynchronizedClosure) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) NodeOptions(com.alipay.sofa.jraft.option.NodeOptions) LogId(com.alipay.sofa.jraft.entity.LogId) ConfigurationManager(com.alipay.sofa.jraft.conf.ConfigurationManager) LogEntry(com.alipay.sofa.jraft.entity.LogEntry) PeerId(com.alipay.sofa.jraft.entity.PeerId)

Aggregations

LogId (com.alipay.sofa.jraft.entity.LogId)44 LogEntry (com.alipay.sofa.jraft.entity.LogEntry)26 PeerId (com.alipay.sofa.jraft.entity.PeerId)18 Test (org.junit.Test)18 Status (com.alipay.sofa.jraft.Status)10 BaseStorageTest (com.alipay.sofa.jraft.storage.BaseStorageTest)9 ArrayList (java.util.ArrayList)8 ConfigurationEntry (com.alipay.sofa.jraft.conf.ConfigurationEntry)7 Configuration (com.alipay.sofa.jraft.conf.Configuration)5 ByteBuffer (java.nio.ByteBuffer)5 LogManager (com.alipay.sofa.jraft.storage.LogManager)4 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 ConfigurationManager (com.alipay.sofa.jraft.conf.ConfigurationManager)3 EntryType (com.alipay.sofa.jraft.entity.EnumOutter.EntryType)2 BaseLogEntryCodecFactoryTest (com.alipay.sofa.jraft.entity.codec.BaseLogEntryCodecFactoryTest)2 RaftException (com.alipay.sofa.jraft.error.RaftException)2 LogStorageOptions (com.alipay.sofa.jraft.option.LogStorageOptions)2 RaftOptions (com.alipay.sofa.jraft.option.RaftOptions)2 DisruptorMetricSet (com.alipay.sofa.jraft.util.DisruptorMetricSet)2