Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -804,28 +804,24 @@ class KRaftClusterTest {
val quorumState = admin.describeMetadataQuorum(new DescribeMetadataQuorumOptions)
val quorumInfo = quorumState.quorumInfo.get()

assertEquals(4, quorumInfo.observers.size)
assertEquals(3, quorumInfo.voters.size)
assertEquals(cluster.controllers.asScala.keySet, quorumInfo.voters.asScala.map(_.replicaId).toSet)
assertTrue(2999 < quorumInfo.leaderId && 3003 > quorumInfo.leaderId,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make this assertion a little more generic by asserting that quorumInfo.leaderId is contained in cluster.controllers.asScala.keySet.

s"Leader ID ${quorumInfo.leaderId} was not within expected range.")

quorumInfo.observers.forEach { observer =>
assertTrue(-1 < observer.replicaId && 4 > observer.replicaId,
s"Observer ID ${observer.replicaId} was not within expected range.")
assertTrue(0 < observer.logEndOffset,
s"logEndOffset for observer with ID ${observer.replicaId} was ${observer.logEndOffset}")
assertNotEquals(OptionalLong.empty(), observer.lastFetchTimeMs)
assertNotEquals(OptionalLong.empty(), observer.lastCaughtUpTimeMs)
}

quorumInfo.voters.forEach { voter =>
assertTrue(2999 < voter.replicaId && 3003 > voter.replicaId,
s"Voter ID ${voter.replicaId} was not within expected range.")
assertTrue(0 < voter.logEndOffset,
s"logEndOffset for voter with ID ${voter.replicaId} was ${voter.logEndOffset}")
assertNotEquals(OptionalLong.empty(), voter.lastFetchTimeMs)
assertNotEquals(OptionalLong.empty(), voter.lastCaughtUpTimeMs)
}

assertEquals(cluster.brokers.asScala.keySet, quorumInfo.observers.asScala.map(_.replicaId).toSet)
quorumInfo.observers.forEach { observer =>
assertTrue(0 < observer.logEndOffset,
s"logEndOffset for observer with ID ${observer.replicaId} was ${observer.logEndOffset}")
assertNotEquals(OptionalLong.empty(), observer.lastFetchTimeMs)
assertNotEquals(OptionalLong.empty(), observer.lastCaughtUpTimeMs)
}
} catch {
case _: InvalidRequestException => log.error("Hit Kafka-13490. Claim test succeeded")
case t: Throwable => throw t

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if we're just re-throwing, we don't need to catch

Expand Down
38 changes: 19 additions & 19 deletions raft/src/main/java/org/apache/kafka/raft/LeaderState.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -208,7 +207,7 @@ private boolean updateHighWatermark() {
/**
* Update the local replica state.
*
* See {@link #updateReplicaState(int, long, LogOffsetMetadata, Long)}
* See {@link #updateReplicaState(int, long, LogOffsetMetadata, long)}
*/
public boolean updateLocalState(long fetchTimestamp, LogOffsetMetadata logOffsetMetadata) {
return updateReplicaState(localId, fetchTimestamp, logOffsetMetadata, logOffsetMetadata.offset);
Expand All @@ -224,10 +223,10 @@ public boolean updateLocalState(long fetchTimestamp, LogOffsetMetadata logOffset
* @return true if the high watermark is updated too
*/
public boolean updateReplicaState(
int replicaId,
long fetchTimestamp,
LogOffsetMetadata logOffsetMetadata,
Long leaderLogEndOffset
int replicaId,
long fetchTimestamp,
LogOffsetMetadata logOffsetMetadata,
long leaderLogEndOffset
) {
// Ignore fetches from negative replica id, as it indicates
// the fetch is from non-replica. For example, a consumer.
Expand Down Expand Up @@ -266,8 +265,8 @@ private List<ReplicaState> followersByDescendingFetchOffset() {
}

private void verifyEndOffsetUpdate(
ReplicaState state,
LogOffsetMetadata endOffsetMetadata
ReplicaState state,
LogOffsetMetadata endOffsetMetadata
) {
state.endOffset.ifPresent(currentEndOffset -> {
if (currentEndOffset.offset > endOffsetMetadata.offset) {
Expand All @@ -282,9 +281,9 @@ private void verifyEndOffsetUpdate(
});
}
private boolean updateEndOffset(
ReplicaState state,
LogOffsetMetadata endOffsetMetadata,
boolean verifyUpdate
ReplicaState state,
LogOffsetMetadata endOffsetMetadata,
boolean verifyUpdate

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? Seems like false is the only value we ever pass.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted to retain the verification step in the method in case we want to use it elsewhere in the future.

) {
if (verifyUpdate) {
verifyEndOffsetUpdate(state, endOffsetMetadata);
Expand Down Expand Up @@ -320,22 +319,23 @@ private ReplicaState getReplicaState(int remoteNodeId) {
}

List<DescribeQuorumResponseData.ReplicaState> quorumResponseVoterStates(long currentTimeMs) {
return quorumResponseReplicaStates(voterStates.values(), OptionalInt.of(localId), currentTimeMs);
return quorumResponseReplicaStates(voterStates.values(), localId, currentTimeMs);
}

List<DescribeQuorumResponseData.ReplicaState> quorumResponseObserverStates(long currentTimeMs) {
clearInactiveObservers(currentTimeMs);
return quorumResponseReplicaStates(observerStates.values(), OptionalInt.empty(), currentTimeMs);
return quorumResponseReplicaStates(observerStates.values(), localId, currentTimeMs);
}

private static <R extends ReplicaState> List<DescribeQuorumResponseData.ReplicaState> quorumResponseReplicaStates(
Collection<R> state,
OptionalInt leaderId,
long currentTimeMs) {
private static List<DescribeQuorumResponseData.ReplicaState> quorumResponseReplicaStates(
Collection<ReplicaState> state,
int leaderId,
long currentTimeMs
) {
return state.stream().map(s -> {
final long lastCaughtUpTimestamp;
final long lastFetchTimestamp;
if (s.nodeId == leaderId.orElse(-1)) {
if (s.nodeId == leaderId) {
lastCaughtUpTimestamp = currentTimeMs;
lastFetchTimestamp = currentTimeMs;
} else {
Expand Down Expand Up @@ -407,7 +407,7 @@ else if (!that.endOffset.isPresent())
public String toString() {
return String.format(
"ReplicaState(nodeId=%d, endOffset=%s, lastFetchTimestamp=%s, " +
" lastCaughtUpTimestamp=%s, hasAcknowledgedLeader=%s)",
"lastCaughtUpTimestamp=%s, hasAcknowledgedLeader=%s)",
nodeId,
endOffset,
lastFetchTimestamp,
Expand Down