use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.
the class V1Decoder method decode.
public void decode(final LogEntry log, final byte[] content) {
// 1-5 type
final int iType = Bits.getInt(content, 1);
log.setType(EnumOutter.EntryType.forNumber(iType));
// 5-13 index
// 13-21 term
final long index = Bits.getLong(content, 5);
final long term = Bits.getLong(content, 13);
log.setId(new LogId(index, term));
// 21-25 peer count
int peerCount = Bits.getInt(content, 21);
// peers
int pos = 25;
if (peerCount > 0) {
List<PeerId> peers = new ArrayList<>(peerCount);
while (peerCount-- > 0) {
final short len = Bits.getShort(content, pos);
final byte[] bs = new byte[len];
System.arraycopy(content, pos + 2, bs, 0, len);
// peer len (short in 2 bytes)
// peer str
pos += 2 + len;
final PeerId peer = new PeerId();
peer.parse(AsciiStringUtil.unsafeDecode(bs));
peers.add(peer);
}
log.setPeers(peers);
}
// old peers
int oldPeerCount = Bits.getInt(content, pos);
pos += 4;
if (oldPeerCount > 0) {
List<PeerId> oldPeers = new ArrayList<>(oldPeerCount);
while (oldPeerCount-- > 0) {
final short len = Bits.getShort(content, pos);
final byte[] bs = new byte[len];
System.arraycopy(content, pos + 2, bs, 0, len);
// peer len (short in 2 bytes)
// peer str
pos += 2 + len;
final PeerId peer = new PeerId();
peer.parse(AsciiStringUtil.unsafeDecode(bs));
oldPeers.add(peer);
}
log.setOldPeers(oldPeers);
}
// data
if (content.length > pos) {
final int len = content.length - pos;
ByteBuffer data = ByteBuffer.allocate(len);
data.put(content, pos, len);
data.flip();
log.setData(data);
}
}
use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.
the class RocksDBLogStorage method reset.
@Override
public boolean reset(final long nextLogIndex) {
if (nextLogIndex <= 0) {
throw new IllegalArgumentException("Invalid next log index.");
}
this.writeLock.lock();
try (final Options opt = new Options()) {
LogEntry entry = getEntry(nextLogIndex);
closeDB();
try {
RocksDB.destroyDB(this.path, opt);
onReset(nextLogIndex);
if (initAndLoad(null)) {
if (entry == null) {
entry = new LogEntry();
entry.setType(EntryType.ENTRY_TYPE_NO_OP);
entry.setId(new LogId(nextLogIndex, 0));
LOG.warn("Entry not found for nextLogIndex {} when reset in data path: {}.", nextLogIndex, this.path);
}
return appendEntry(entry);
} else {
return false;
}
} catch (final RocksDBException e) {
LOG.error("Fail to reset next log index.", e);
return false;
}
} finally {
this.writeLock.unlock();
}
}
use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.
the class LogManagerImpl method init.
@Override
public boolean init(final LogManagerOptions opts) {
this.writeLock.lock();
try {
if (opts.getLogStorage() == null) {
LOG.error("Fail to init log manager, log storage is null");
return false;
}
this.raftOptions = opts.getRaftOptions();
this.nodeMetrics = opts.getNodeMetrics();
this.logStorage = opts.getLogStorage();
this.configManager = opts.getConfigurationManager();
LogStorageOptions lsOpts = new LogStorageOptions();
lsOpts.setConfigurationManager(this.configManager);
lsOpts.setLogEntryCodecFactory(opts.getLogEntryCodecFactory());
if (!this.logStorage.init(lsOpts)) {
LOG.error("Fail to init logStorage");
return false;
}
this.firstLogIndex = this.logStorage.getFirstLogIndex();
this.lastLogIndex = this.logStorage.getLastLogIndex();
this.diskId = new LogId(this.lastLogIndex, getTermFromLogStorage(this.lastLogIndex));
this.fsmCaller = opts.getFsmCaller();
this.disruptor = //
DisruptorBuilder.<StableClosureEvent>newInstance().setEventFactory(//
new StableClosureEventFactory()).setRingBufferSize(//
opts.getDisruptorBufferSize()).setThreadFactory(//
new NamedThreadFactory("JRaft-LogManager-Disruptor-", true)).setProducerType(//
ProducerType.MULTI).setWaitStrategy(new TimeoutBlockingWaitStrategy(this.raftOptions.getDisruptorPublishEventWaitTimeoutSecs(), //
TimeUnit.SECONDS)).build();
this.disruptor.handleEventsWith(new StableClosureEventHandler());
this.disruptor.setDefaultExceptionHandler(new LogExceptionHandler<Object>(this.getClass().getSimpleName(), (event, ex) -> reportError(-1, "LogManager handle event error")));
this.diskQueue = this.disruptor.start();
if (this.nodeMetrics.getMetricRegistry() != null) {
this.nodeMetrics.getMetricRegistry().register("jraft-log-manager-disruptor", new DisruptorMetricSet(this.diskQueue));
}
} finally {
this.writeLock.unlock();
}
return true;
}
use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.
the class LogManagerImpl method checkConsistency.
@Override
public Status checkConsistency() {
this.readLock.lock();
try {
Requires.requireTrue(this.firstLogIndex > 0);
Requires.requireTrue(this.lastLogIndex >= 0);
if (this.lastSnapshotId.equals(new LogId(0, 0))) {
if (this.firstLogIndex == 1) {
return Status.OK();
}
return new Status(RaftError.EIO, "Missing logs in (0, %d)", this.firstLogIndex);
} else {
if (this.lastSnapshotId.getIndex() >= this.firstLogIndex - 1 && this.lastSnapshotId.getIndex() <= this.lastLogIndex) {
return Status.OK();
}
return new Status(RaftError.EIO, "There's a gap between snapshot={%d, %d} and log=[%d, %d] ", this.lastSnapshotId.toString(), this.lastSnapshotId.getTerm(), this.firstLogIndex, this.lastLogIndex);
}
} finally {
this.readLock.unlock();
}
}
use of com.alipay.sofa.jraft.entity.LogId in project sofa-jraft by sofastack.
the class LogManagerImpl method setSnapshot.
@Override
public void setSnapshot(final SnapshotMeta meta) {
LOG.debug("set snapshot: {}.", meta);
boolean doUnlock = true;
this.writeLock.lock();
try {
if (meta.getLastIncludedIndex() <= this.lastSnapshotId.getIndex()) {
return;
}
final Configuration conf = confFromMeta(meta);
final Configuration oldConf = oldConfFromMeta(meta);
final ConfigurationEntry entry = new ConfigurationEntry(new LogId(meta.getLastIncludedIndex(), meta.getLastIncludedTerm()), conf, oldConf);
this.configManager.setSnapshot(entry);
final long term = unsafeGetTerm(meta.getLastIncludedIndex());
final long savedLastSnapshotIndex = this.lastSnapshotId.getIndex();
this.lastSnapshotId.setIndex(meta.getLastIncludedIndex());
this.lastSnapshotId.setTerm(meta.getLastIncludedTerm());
if (this.lastSnapshotId.compareTo(this.appliedId) > 0) {
this.appliedId = this.lastSnapshotId.copy();
}
if (term == 0) {
// last_included_index is larger than last_index
// FIXME: what if last_included_index is less than first_index?
doUnlock = false;
// unlock in truncatePrefix
truncatePrefix(meta.getLastIncludedIndex() + 1, this.writeLock);
} else if (term == meta.getLastIncludedTerm()) {
// TODO if there are still be need?
if (savedLastSnapshotIndex > 0) {
doUnlock = false;
// unlock in truncatePrefix
truncatePrefix(savedLastSnapshotIndex + 1, this.writeLock);
}
} else {
if (!reset(meta.getLastIncludedIndex() + 1)) {
LOG.warn("Reset log manager failed, nextLogIndex={}.", meta.getLastIncludedIndex() + 1);
}
}
} finally {
if (doUnlock) {
this.writeLock.unlock();
}
}
}
Aggregations