use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.
the class GrpcLogAppender method installSnapshot.
/**
* Send installSnapshot request to Follower with a snapshot.
* @param snapshot the snapshot to be sent to Follower
*/
private void installSnapshot(SnapshotInfo snapshot) {
LOG.info("{}: followerNextIndex = {} but logStartIndex = {}, send snapshot {} to follower", this, getFollower().getNextIndex(), getRaftLog().getStartIndex(), snapshot);
final InstallSnapshotResponseHandler responseHandler = new InstallSnapshotResponseHandler();
StreamObserver<InstallSnapshotRequestProto> snapshotRequestObserver = null;
final String requestId = UUID.randomUUID().toString();
try {
snapshotRequestObserver = getClient().installSnapshot(responseHandler);
for (InstallSnapshotRequestProto request : newInstallSnapshotRequests(requestId, snapshot)) {
if (isRunning()) {
snapshotRequestObserver.onNext(request);
getFollower().updateLastRpcSendTime(false);
responseHandler.addPending(request);
} else {
break;
}
}
snapshotRequestObserver.onCompleted();
grpcServerMetrics.onInstallSnapshot();
} catch (Exception e) {
LOG.warn("{}: failed to install snapshot {}: {}", this, snapshot.getFiles(), e);
if (snapshotRequestObserver != null) {
snapshotRequestObserver.onError(e);
}
return;
}
while (isRunning() && !responseHandler.isDone()) {
try {
getEventAwaitForSignal().await();
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
}
if (responseHandler.hasAllResponse()) {
getFollower().setSnapshotIndex(snapshot.getTermIndex().getIndex());
LOG.info("{}: installed snapshot {} successfully", this, snapshot);
}
}
use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.
the class GrpcLogAppender method installSnapshot.
/**
* Send installSnapshot request to Follower with only a notification that a snapshot needs to be installed.
* @param firstAvailableLogTermIndex the first available log's index on the Leader
*/
private void installSnapshot(TermIndex firstAvailableLogTermIndex) {
LOG.info("{}: followerNextIndex = {} but logStartIndex = {}, notify follower to install snapshot-{}", this, getFollower().getNextIndex(), getRaftLog().getStartIndex(), firstAvailableLogTermIndex);
final InstallSnapshotResponseHandler responseHandler = new InstallSnapshotResponseHandler(true);
StreamObserver<InstallSnapshotRequestProto> snapshotRequestObserver = null;
// prepare and enqueue the notify install snapshot request.
final InstallSnapshotRequestProto request = newInstallSnapshotNotificationRequest(firstAvailableLogTermIndex);
if (LOG.isInfoEnabled()) {
LOG.info("{}: send {}", this, ServerStringUtils.toInstallSnapshotRequestString(request));
}
try {
snapshotRequestObserver = getClient().installSnapshot(responseHandler);
snapshotRequestObserver.onNext(request);
getFollower().updateLastRpcSendTime(false);
responseHandler.addPending(request);
snapshotRequestObserver.onCompleted();
} catch (Exception e) {
GrpcUtil.warn(LOG, () -> this + ": Failed to notify follower to install snapshot.", e);
if (snapshotRequestObserver != null) {
snapshotRequestObserver.onError(e);
}
return;
}
while (isRunning() && !responseHandler.isDone()) {
try {
getEventAwaitForSignal().await();
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
}
}
use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.
the class LogAppenderDefault method installSnapshot.
private InstallSnapshotReplyProto installSnapshot(SnapshotInfo snapshot) throws InterruptedIOException {
String requestId = UUID.randomUUID().toString();
InstallSnapshotReplyProto reply = null;
try {
for (InstallSnapshotRequestProto request : newInstallSnapshotRequests(requestId, snapshot)) {
getFollower().updateLastRpcSendTime(false);
reply = getServerRpc().installSnapshot(request);
getFollower().updateLastRpcResponseTime();
if (!reply.getServerReply().getSuccess()) {
return reply;
}
}
} catch (InterruptedIOException iioe) {
throw iioe;
} catch (Exception ioe) {
LOG.warn("{}: Failed to installSnapshot {}: {}", this, snapshot, ioe);
handleException(ioe);
return null;
}
if (reply != null) {
getFollower().setSnapshotIndex(snapshot.getTermIndex().getIndex());
LOG.info("{}: installSnapshot {} successfully", this, snapshot);
getServer().getRaftServerMetrics().onSnapshotInstalled();
}
return reply;
}
use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.
the class SnapshotManager method installSnapshot.
@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
public void installSnapshot(StateMachine stateMachine, InstallSnapshotRequestProto request) throws IOException {
final InstallSnapshotRequestProto.SnapshotChunkProto snapshotChunkRequest = request.getSnapshotChunk();
final long lastIncludedIndex = snapshotChunkRequest.getTermIndex().getIndex();
final RaftStorageDirectory dir = storage.getStorageDir();
// create a unique temporary directory
final File tmpDir = new File(dir.getTmpDir(), UUID.randomUUID().toString());
FileUtils.createDirectories(tmpDir);
tmpDir.deleteOnExit();
LOG.info("Installing snapshot:{}, to tmp dir:{}", request, tmpDir);
for (FileChunkProto chunk : snapshotChunkRequest.getFileChunksList()) {
SnapshotInfo pi = stateMachine.getLatestSnapshot();
if (pi != null && pi.getTermIndex().getIndex() >= lastIncludedIndex) {
throw new IOException("There exists snapshot file " + pi.getFiles() + " in " + selfId + " with endIndex >= lastIncludedIndex " + lastIncludedIndex);
}
// this is relative to the root dir
String fileName = chunk.getFilename();
// TODO: assumes flat layout inside SM dir
File tmpSnapshotFile = new File(tmpDir, new File(dir.getRoot(), fileName).getName());
FileOutputStream out = null;
try {
// same last index.
if (chunk.getOffset() == 0) {
if (tmpSnapshotFile.exists()) {
FileUtils.deleteFully(tmpSnapshotFile);
}
// create the temp snapshot file and put padding inside
out = new FileOutputStream(tmpSnapshotFile);
} else {
Preconditions.assertTrue(tmpSnapshotFile.exists());
out = new FileOutputStream(tmpSnapshotFile, true);
FileChannel fc = out.getChannel();
fc.position(chunk.getOffset());
}
// write data to the file
out.write(chunk.getData().toByteArray());
} finally {
IOUtils.cleanup(null, out);
}
// the md5 digest and create the md5 meta-file.
if (chunk.getDone()) {
final MD5Hash expectedDigest = new MD5Hash(chunk.getFileDigest().toByteArray());
// calculate the checksum of the snapshot file and compare it with the
// file digest in the request
MD5Hash digest = MD5FileUtil.computeMd5ForFile(tmpSnapshotFile);
if (!digest.equals(expectedDigest)) {
LOG.warn("The snapshot md5 digest {} does not match expected {}", digest, expectedDigest);
// rename the temp snapshot file to .corrupt
FileUtils.renameFileToCorrupt(tmpSnapshotFile);
throw new CorruptedFileException(tmpSnapshotFile, "MD5 mismatch for snapshot-" + lastIncludedIndex + " installation");
} else {
MD5FileUtil.saveMD5File(tmpSnapshotFile, digest);
}
}
}
if (snapshotChunkRequest.getDone()) {
LOG.info("Install snapshot is done, renaming tnp dir:{} to:{}", tmpDir, dir.getStateMachineDir());
dir.getStateMachineDir().delete();
tmpDir.renameTo(dir.getStateMachineDir());
}
}
Aggregations