use of com.alipay.sofa.jraft.entity.LogEntry in project sofa-jraft by sofastack.
the class RocksDBLogStorage method appendEntries.
@Override
public int appendEntries(final List<LogEntry> entries) {
if (entries == null || entries.isEmpty()) {
return 0;
}
final int entriesCount = entries.size();
final boolean ret = executeBatch(batch -> {
final WriteContext writeCtx = newWriteContext();
for (int i = 0; i < entriesCount; i++) {
final LogEntry entry = entries.get(i);
if (entry.getType() == EntryType.ENTRY_TYPE_CONFIGURATION) {
addConfBatch(entry, batch);
} else {
writeCtx.startJob();
addDataBatch(entry, batch, writeCtx);
}
}
writeCtx.joinAll();
doSync();
});
if (ret) {
return entriesCount;
} else {
return 0;
}
}
use of com.alipay.sofa.jraft.entity.LogEntry in project sofa-jraft by sofastack.
the class V2Decoder method decode.
@Override
public LogEntry decode(final byte[] bs) {
if (bs == null || bs.length < LogEntryV2CodecFactory.HEADER_SIZE) {
return null;
}
int i = 0;
for (; i < LogEntryV2CodecFactory.MAGIC_BYTES.length; i++) {
if (bs[i] != LogEntryV2CodecFactory.MAGIC_BYTES[i]) {
return null;
}
}
if (bs[i++] != LogEntryV2CodecFactory.VERSION) {
return null;
}
// Ignored reserved
i += LogEntryV2CodecFactory.RESERVED.length;
try {
final PBLogEntry entry = PBLogEntry.parseFrom(ZeroByteStringHelper.wrap(bs, i, bs.length - i));
final LogEntry log = new LogEntry();
log.setType(entry.getType());
log.getId().setIndex(entry.getIndex());
log.getId().setTerm(entry.getTerm());
if (entry.hasChecksum()) {
log.setChecksum(entry.getChecksum());
}
if (entry.getPeersCount() > 0) {
final List<PeerId> peers = new ArrayList<>(entry.getPeersCount());
for (final ByteString bstring : entry.getPeersList()) {
peers.add(JRaftUtils.getPeerId(AsciiStringUtil.unsafeDecode(bstring)));
}
log.setPeers(peers);
}
if (entry.getOldPeersCount() > 0) {
final List<PeerId> peers = new ArrayList<>(entry.getOldPeersCount());
for (final ByteString bstring : entry.getOldPeersList()) {
peers.add(JRaftUtils.getPeerId(AsciiStringUtil.unsafeDecode(bstring)));
}
log.setOldPeers(peers);
}
if (entry.getLearnersCount() > 0) {
final List<PeerId> peers = new ArrayList<>(entry.getLearnersCount());
for (final ByteString bstring : entry.getLearnersList()) {
peers.add(JRaftUtils.getPeerId(AsciiStringUtil.unsafeDecode(bstring)));
}
log.setLearners(peers);
}
if (entry.getOldLearnersCount() > 0) {
final List<PeerId> peers = new ArrayList<>(entry.getOldLearnersCount());
for (final ByteString bstring : entry.getOldLearnersList()) {
peers.add(JRaftUtils.getPeerId(AsciiStringUtil.unsafeDecode(bstring)));
}
log.setOldLearners(peers);
}
final ByteString data = entry.getData();
if (!data.isEmpty()) {
log.setData(ByteBuffer.wrap(ZeroByteStringHelper.getByteArray(data)));
}
return log;
} catch (final InvalidProtocolBufferException e) {
LOG.error("Fail to decode pb log entry", e);
return null;
}
}
use of com.alipay.sofa.jraft.entity.LogEntry 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;
}
use of com.alipay.sofa.jraft.entity.LogEntry 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;
}
use of com.alipay.sofa.jraft.entity.LogEntry in project sofa-jraft by sofastack.
the class NodeImpl method apply.
@Override
public void apply(final Task task) {
if (this.shutdownLatch != null) {
Utils.runClosureInThread(task.getDone(), new Status(RaftError.ENODESHUTDOWN, "Node is shutting down."));
throw new IllegalStateException("Node is shutting down");
}
Requires.requireNonNull(task, "Null task");
final LogEntry entry = new LogEntry();
entry.setData(task.getData());
final EventTranslator<LogEntryAndClosure> translator = (event, sequence) -> {
event.reset();
event.done = task.getDone();
event.entry = entry;
event.expectedTerm = task.getExpectedTerm();
};
switch(this.options.getApplyTaskMode()) {
case Blocking:
this.applyQueue.publishEvent(translator);
break;
case NonBlocking:
default:
if (!this.applyQueue.tryPublishEvent(translator)) {
String errorMsg = "Node is busy, has too many tasks, queue is full and bufferSize=" + this.applyQueue.getBufferSize();
Utils.runClosureInThread(task.getDone(), new Status(RaftError.EBUSY, errorMsg));
LOG.warn("Node {} applyQueue is overload.", getNodeId());
this.metrics.recordTimes("apply-task-overload-times", 1);
if (task.getDone() == null) {
throw new OverloadException(errorMsg);
}
}
break;
}
}
Aggregations