use of com.alipay.sofa.jraft.storage.snapshot.SnapshotReader in project nacos by alibaba.
the class NacosStateMachine method adapterToJRaftSnapshot.
private void adapterToJRaftSnapshot(Collection<SnapshotOperation> userOperates) {
List<JSnapshotOperation> tmp = new ArrayList<>();
for (SnapshotOperation item : userOperates) {
if (item == null) {
Loggers.RAFT.error("Existing SnapshotOperation for null");
continue;
}
tmp.add(new JSnapshotOperation() {
@Override
public void onSnapshotSave(SnapshotWriter writer, Closure done) {
final Writer wCtx = new Writer(writer.getPath());
// Do a layer of proxy operation to shield different Raft
// components from implementing snapshots
final BiConsumer<Boolean, Throwable> callFinally = (result, t) -> {
boolean[] results = new boolean[wCtx.listFiles().size()];
int[] index = new int[] { 0 };
wCtx.listFiles().forEach((file, meta) -> {
try {
results[index[0]++] = writer.addFile(file, buildMetadata(meta));
} catch (Exception e) {
throw new ConsistencyException(e);
}
});
final Status status = result && !Arrays.asList(results).stream().anyMatch(Boolean.FALSE::equals) ? Status.OK() : new Status(RaftError.EIO, "Fail to compress snapshot at %s, error is %s", writer.getPath(), t == null ? "" : t.getMessage());
done.run(status);
};
item.onSnapshotSave(wCtx, callFinally);
}
@Override
public boolean onSnapshotLoad(SnapshotReader reader) {
final Map<String, LocalFileMeta> metaMap = new HashMap<>(reader.listFiles().size());
for (String fileName : reader.listFiles()) {
final LocalFileMetaOutter.LocalFileMeta meta = (LocalFileMetaOutter.LocalFileMeta) reader.getFileMeta(fileName);
byte[] bytes = meta.getUserMeta().toByteArray();
final LocalFileMeta fileMeta;
if (bytes == null || bytes.length == 0) {
fileMeta = new LocalFileMeta();
} else {
fileMeta = JacksonUtils.toObj(bytes, LocalFileMeta.class);
}
metaMap.put(fileName, fileMeta);
}
final Reader rCtx = new Reader(reader.getPath(), metaMap);
return item.onSnapshotLoad(rCtx);
}
@Override
public String info() {
return item.toString();
}
});
}
this.operations = Collections.unmodifiableList(tmp);
}
use of com.alipay.sofa.jraft.storage.snapshot.SnapshotReader in project sofa-jraft by sofastack.
the class FSMCallerTest method testOnSnapshotLoadFSMError.
@Test
public void testOnSnapshotLoadFSMError() throws Exception {
final SnapshotReader reader = Mockito.mock(SnapshotReader.class);
final SnapshotMeta meta = SnapshotMeta.newBuilder().setLastIncludedIndex(12).setLastIncludedTerm(1).build();
Mockito.when(reader.load()).thenReturn(meta);
Mockito.when(this.fsm.onSnapshotLoad(reader)).thenReturn(false);
final CountDownLatch latch = new CountDownLatch(1);
this.fsmCaller.onSnapshotLoad(new LoadSnapshotClosure() {
@Override
public void run(final Status status) {
assertFalse(status.isOk());
assertEquals(-1, status.getCode());
assertEquals("StateMachine onSnapshotLoad failed", status.getErrorMsg());
latch.countDown();
}
@Override
public SnapshotReader start() {
return reader;
}
});
latch.await();
assertEquals(this.fsmCaller.getLastAppliedIndex(), 10);
}
use of com.alipay.sofa.jraft.storage.snapshot.SnapshotReader in project sofa-jraft by sofastack.
the class LocalSnapshotCopierTest method testInterrupt.
@Test
public void testInterrupt() throws Exception {
final FutureImpl<Message> future = new FutureImpl<>();
final RpcRequests.GetFileRequest.Builder rb = RpcRequests.GetFileRequest.newBuilder().setReaderId(99).setFilename(Snapshot.JRAFT_SNAPSHOT_META_FILE).setCount(Integer.MAX_VALUE).setOffset(0).setReadPartly(true);
// mock get metadata
final ArgumentCaptor<RpcResponseClosure> argument = ArgumentCaptor.forClass(RpcResponseClosure.class);
Mockito.when(this.raftClientService.getFile(eq(new Endpoint("localhost", 8081)), eq(rb.build()), eq(this.copyOpts.getTimeoutMs()), argument.capture())).thenReturn(future);
this.copier.start();
Thread.sleep(10);
Utils.runInThread(new Runnable() {
@Override
public void run() {
LocalSnapshotCopierTest.this.copier.cancel();
}
});
this.copier.join();
// start timer
final SnapshotReader reader = this.copier.getReader();
assertNull(reader);
Assert.assertEquals(RaftError.ECANCELED.getNumber(), this.copier.getCode());
Assert.assertEquals("Cancel the copier manually.", this.copier.getErrorMsg());
}
use of com.alipay.sofa.jraft.storage.snapshot.SnapshotReader in project sofa-jraft by sofastack.
the class LocalSnapshotStorage method copyFrom.
@Override
public SnapshotReader copyFrom(final String uri, final SnapshotCopierOptions opts) {
final SnapshotCopier copier = startToCopyFrom(uri, opts);
if (copier == null) {
return null;
}
try {
copier.join();
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
LOG.error("Join on snapshot copier was interrupted.");
return null;
}
final SnapshotReader reader = copier.getReader();
Utils.closeQuietly(copier);
return reader;
}
use of com.alipay.sofa.jraft.storage.snapshot.SnapshotReader in project sofa-jraft by sofastack.
the class FSMCallerImpl method doSnapshotLoad.
private void doSnapshotLoad(final LoadSnapshotClosure done) {
Requires.requireNonNull(done, "LoadSnapshotClosure is null");
final SnapshotReader reader = done.start();
if (reader == null) {
done.run(new Status(RaftError.EINVAL, "open SnapshotReader failed"));
return;
}
final RaftOutter.SnapshotMeta meta = reader.load();
if (meta == null) {
done.run(new Status(RaftError.EINVAL, "SnapshotReader load meta failed"));
if (reader.getRaftError() == RaftError.EIO) {
final RaftException err = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_SNAPSHOT, RaftError.EIO, "Fail to load snapshot meta");
setError(err);
}
return;
}
final LogId lastAppliedId = new LogId(this.lastAppliedIndex.get(), this.lastAppliedTerm);
final LogId snapshotId = new LogId(meta.getLastIncludedIndex(), meta.getLastIncludedTerm());
if (lastAppliedId.compareTo(snapshotId) > 0) {
done.run(new Status(RaftError.ESTALE, "Loading a stale snapshot last_applied_index=%d last_applied_term=%d snapshot_index=%d snapshot_term=%d", lastAppliedId.getIndex(), lastAppliedId.getTerm(), snapshotId.getIndex(), snapshotId.getTerm()));
return;
}
if (!this.fsm.onSnapshotLoad(reader)) {
done.run(new Status(-1, "StateMachine onSnapshotLoad failed"));
final RaftException e = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_STATE_MACHINE, RaftError.ESTATEMACHINE, "StateMachine onSnapshotLoad failed");
setError(e);
return;
}
if (meta.getOldPeersCount() == 0) {
// Joint stage is not supposed to be noticeable by end users.
final Configuration conf = new Configuration();
for (int i = 0, size = meta.getPeersCount(); i < size; i++) {
final PeerId peer = new PeerId();
Requires.requireTrue(peer.parse(meta.getPeers(i)), "Parse peer failed");
conf.addPeer(peer);
}
this.fsm.onConfigurationCommitted(conf);
}
this.lastAppliedIndex.set(meta.getLastIncludedIndex());
this.lastAppliedTerm = meta.getLastIncludedTerm();
done.run(Status.OK());
}
Aggregations