All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.permazen.kv.raft.msg.AppendResponse Maven / Gradle / Ivy


/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.kv.raft.msg;

import com.google.common.base.Preconditions;

import io.permazen.kv.raft.Timestamp;
import io.permazen.util.LongEncoder;

import java.nio.ByteBuffer;

/**
 * Sent from a follower to a leader in response to an {@link AppendRequest}.
 *
 * 

* Also contains information about the follower's log. */ public class AppendResponse extends Message { private final Timestamp leaderTimestamp; // leaderTimestamp from corresponding AppendRequest private final boolean success; // true if previous log entry term and index matched private final long matchIndex; // index of highest log entry known to match leader private final long lastLogIndex; // the index of the last log entry in follower's log // Constructors /** * Constructor. * * @param clusterId cluster ID * @param senderId identity of sender * @param recipientId identity of recipient * @param term sender's current term * @param leaderTimestamp copy of {@link AppendRequest#getLeaderTimestamp} * @param success if request successfully matched * @param matchIndex highest known matching log index * @param lastLogIndex index of follower's last log entry */ @SuppressWarnings("this-escape") public AppendResponse(int clusterId, String senderId, String recipientId, long term, Timestamp leaderTimestamp, boolean success, long matchIndex, long lastLogIndex) { super(Message.APPEND_RESPONSE_TYPE, clusterId, senderId, recipientId, term); this.leaderTimestamp = leaderTimestamp; this.success = success; this.matchIndex = matchIndex; this.lastLogIndex = lastLogIndex; this.checkArguments(); } AppendResponse(ByteBuffer buf, int version) { super(Message.APPEND_RESPONSE_TYPE, buf, version); this.leaderTimestamp = Message.getTimestamp(buf, version); this.success = Message.getBoolean(buf); this.matchIndex = LongEncoder.read(buf); this.lastLogIndex = LongEncoder.read(buf); this.checkArguments(); } @Override void checkArguments() { super.checkArguments(); Preconditions.checkArgument(this.leaderTimestamp != null); Preconditions.checkArgument(this.matchIndex >= -1); Preconditions.checkArgument(this.matchIndex <= this.lastLogIndex); } // Properties /** * Get the {@code leaderTimestamp} from the corresponding {@link AppendRequest}. * * @return request leader timestamp * @see AppendRequest#getLeaderTimestamp */ public Timestamp getLeaderTimestamp() { return this.leaderTimestamp; } /** * Determine whether the request was successful, i.e., the previous log entry term and index matched. * * @return true if the corresponding request matched */ public boolean isSuccess() { return this.success; } /** * Get the index of the most recent log entry known to match leader. * In case of a successful request, this will be equal to the log entry sent (or the previous * log entry in case of a probe). In case of a failed request, this will be equal * to the follower's state machine last applied index. * * @return highest known matching log entry index */ public long getMatchIndex() { return this.matchIndex; } /** * Get the index of the last log entry in the follower's log. * * @return last log entry index */ public long getLastLogIndex() { return this.lastLogIndex; } // Message @Override public void visit(MessageSwitch handler) { handler.caseAppendResponse(this); } @Override public void writeTo(ByteBuffer dest, int version) { super.writeTo(dest, version); Message.putTimestamp(dest, this.leaderTimestamp, version); Message.putBoolean(dest, this.success); LongEncoder.write(dest, this.matchIndex); LongEncoder.write(dest, this.lastLogIndex); } @Override protected int calculateSize(int version) { return super.calculateSize(version) + Message.calculateSize(this.leaderTimestamp, version) + 1 + LongEncoder.encodeLength(this.matchIndex) + LongEncoder.encodeLength(this.lastLogIndex); } // Object @Override public String toString() { return this.getClass().getSimpleName() + "[\"" + this.getSenderId() + "\"->\"" + this.getRecipientId() + "\"" + ",clusterId=" + String.format("%08x", this.getClusterId()) + ",term=" + this.getTerm() + ",leaderTimestamp=" + this.leaderTimestamp + ",success=" + this.success + ",matchIndex=" + this.matchIndex + ",lastLogIndex=" + this.lastLogIndex + "]"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy