Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejs
git diff upstream/trunk clients/src/main/resources/common/message/BeginQuorumEpochResponse.json
diff --git a/clients/src/main/resources/common/message/BeginQuorumEpochResponse.json b/clients/src/main/resources/common/message/BeginQuorumEpochResponse.json
index 4b7d7f5a95..12639bba2f 100644
--- a/clients/src/main/resources/common/message/BeginQuorumEpochResponse.json
+++ b/clients/src/main/resources/common/message/BeginQuorumEpochResponse.json
@@ -17,25 +17,32 @@
   "apiKey": 53,
   "type": "response",
   "name": "BeginQuorumEpochResponse",
-  "validVersions": "0",
-  "flexibleVersions": "none",
+  "validVersions": "0-1",
+  "flexibleVersions": "1+",
   "fields": [
     { "name": "ErrorCode", "type": "int16", "versions": "0+",
       "about": "The top level error code"},
     { "name": "Topics", "type": "[]TopicData",
       "versions": "0+", "fields": [
       { "name": "TopicName", "type": "string", "versions": "0+", "entityType": "topicName",
         "about": "The topic name" },
       { "name": "Partitions", "type": "[]PartitionData",
         "versions": "0+", "fields": [
         { "name": "PartitionIndex", "type": "int32", "versions": "0+",
           "about": "The partition index" },
         { "name": "ErrorCode", "type": "int16", "versions": "0+"},
         { "name": "LeaderId", "type": "int32", "versions": "0+", "entityType": "brokerId",
           "about": "The ID of the current leader or -1 if the leader is unknown"},
         { "name": "LeaderEpoch", "type": "int32", "versions": "0+",
           "about": "The latest known leader epoch"}
       ]}
+    ]},
+    { "name": "NodeEndpoints", "type": "[]NodeEndpoint", "versions": "1+", "taggedVersions": "1+", "tag": 0,
+      "about": "Endpoints for all leaders enumerated in PartitionData", "fields": [
+      { "name": "NodeId", "type": "int32", "versions": "1+",
+        "mapKey": true, "entityType": "brokerId", "about": "The ID of the associated node" },
+      { "name": "Host", "type": "string", "versions": "1+", "about": "The node's hostname" },
+      { "name": "Port", "type": "int32", "versions": "1+", "about": "The node's port" }
     ]}
   ]
 }

Fetch

Request

EndQuorumEpoch

In addition to the current cases where the leader resigns and sends an EndQuorumEpoch RPC, the leader will also resign and send this RPC once a RemoveVoterRecord has committed and it is for the current leader. 

Handling

This request will be handle similar to how it is described in KIP-595. The receiving replica will take the directory id (candidate uuid) into account when computing the fetch timeout exponential backoff.

Request

PreferredSuccessor which is an array is replica ids, will be replaced by PreferredCandidates which is an array of the tuple candidate id and candidate uuidVersion 14 adds the field ReplicaUuid to the FetchPartition. This field is populated with the replica generated UUID. If the ReplicaUuid and the ReplicaId fields are populated, the topic partition leader can assume that the replica supports becoming a voter.

Code Block
languagejs
{
git  "apiKey": 1,
  "type"diff upstream/trunk clients/src/main/resources/common/message/EndQuorumEpochRequest.json
diff --git a/clients/src/main/resources/common/message/EndQuorumEpochRequest.json b/clients/src/main/resources/common/message/EndQuorumEpochRequest.json
index a6e4076412..d9122fa930 100644
--- a/clients/src/main/resources/common/message/EndQuorumEpochRequest.json
+++ b/clients/src/main/resources/common/message/EndQuorumEpochRequest.json
@@ -18,8 +18,8 @@
   "type": "request",
   "listeners": ["zkBrokercontroller"],
   "name": "brokerEndQuorumEpochRequest",
-  "validVersions": "controller0"],
-  "nameflexibleVersions": "FetchRequestnone",
+  "validVersions": "0-141",
+  "flexibleVersions": "121+",
   "fields": [
     { "name": "ClusterId", "type": "string", "versions": "120+",
       "nullableVersions": "120+", "default": "null"}, "taggedVersions": "12+", "tag": 0, "ignorable": true,

@@ -35,8 +35,13 @@
           "about": "The clusterIdcurrent ifleader known.ID Thisthat is usedresigning"},
 to validate metadata fetches prior to broker registration." },
    { "name": "ReplicaIdLeaderEpoch", "type": "int32", "versions": "0+", "entityType": "brokerId",

           "about": "The replica ID of the follower, of -1 if this request is from a consumer." current epoch"},
-    ...
    { "name": "TopicsPreferredSuccessors", "type": "[]FetchTopicint32", "versions": "0+",
-          "about": "The topicsA sorted list of preferred successors to fetch.", "fields": [
 start the election"}
+      {  { "name": "TopicPreferredSuccessors", "type": "string[]int32", "versions": "0-12",
+ "entityType": "topicName", "ignorable": true,
        "about": "TheA sorted namelist of thepreferred topicsuccessors to fetch. start the election" },
+        { "name": "TopicIdPreferredCandidates", "type": "uuid[]ReplicaInfo", "versions": "131+",
+ "ignorable": true,
        "about": "The unique topic ID"},
A sorted list of preferred successors to start the election", "fields": [
+          { "name": "PartitionsCandidateId", "type": "[]FetchPartitionint32", "versions": "01+",
        "aboutentityType": "brokerId"The partitions to fetch.", "fields": [
 },
+          { "name": "PartitionCandidateUuid", "type": "int32uuid", "versions": "01+", }
+        ]}
   "about": "The partition index." ]},
        { "name": "ReplicaUuid", 
     ]}
   ]

Response

Code Block
languagejs
git diff upstream/trunk clients/src/main/resources/common/message/EndQuorumEpochResponse.json
diff --git a/clients/src/main/resources/common/message/EndQuorumEpochResponse.json b/clients/src/main/resources/common/message/EndQuorumEpochResponse.json
index cd23247045..0d5d61b7e7 100644
--- a/clients/src/main/resources/common/message/EndQuorumEpochResponse.json
+++ b/clients/src/main/resources/common/message/EndQuorumEpochResponse.json
@@ -17,8 +17,8 @@
   "apiKey": 54,
   "type": "uuidresponse",
 "versions": "14+", "nullableVersionsname": "14+EndQuorumEpochResponse", "default": "null",
       
-   "aboutvalidVersions": "The replica generated UUID. null otherwise." }0",
        ...
      ]}
    ]}
  ]
}

Response

Version 14 rename LeaderIdAndEpoch to CurrentLeader and adds Endpoint to CurrentLeader.

Code Block
{
  "apiKey": 1,
  "type": "response",
  "name": "FetchResponse",
  "-  "flexibleVersions": "none",
+  "validVersions": "0-141",
+  "flexibleVersions": "121+",
   "fields": [
    ...
    { "name": "ResponsesErrorCode", "type": "[]FetchableTopicResponseint16", "versions": "0+",
       "about": "The top responselevel error topicscode."}, "fields": [

@@ -36,6 +36,13 @@
         { "name": "TopicLeaderEpoch", "type": "stringint32", "versions": "0-12+", "ignorable": true, "entityType": "topicName",

           "about": "The latest known topicleader name." },
epoch"}
       ]}
+    ]},
+    { "name": "TopicIdNodeEndpoints", "type": "uuid[]NodeEndpoint", "versions": "1+", "13taggedVersions": "1+", "ignorabletag": true,0,
+      "about": "The unique topic ID"},
Endpoints for all leaders enumerated in PartitionData", "fields": [
+      { "name": "PartitionsNodeId", "type": "[]PartitionDataint32", "versions": "01+",
+        "aboutmapKey": true, "entityType"The topic partitions.: "brokerId", "fieldsabout": [
     "The ID of the associated node" },
+   ...
        { "name": "CurrentLeaderHost", "type": "CurrentLeaderstring",
          "versions": "121+", "taggedVersionsabout": "12+", "tag": 1, "fields": [
The node's hostname" },
+           { "name": "LeaderIdPort", "type": "int32", "versions": "121+", "defaultabout": "-1", "entityType": "brokerId",The node's port" }
     ]}
   ]
 }

Fetch

Request

Version 14 adds the field ReplicaUuid to the FetchPartition. This field is populated with the replica generated UUID. If the ReplicaUuid and the ReplicaId fields are populated, the topic partition leader can assume that the replica supports becoming a voter.

Code Block
languagejs
{
  "apiKey": 1,
  "abouttype": "Therequest",
 ID of the current leader or -1 if the leader is unknown."},
       "listeners": ["zkBroker", "broker", "controller"],
  "name": "FetchRequest",
  "validVersions": "0-14",
  "flexibleVersions": "12+",
  "fields": [
    { "name": "LeaderEpochClusterId", "type": "int32string", "versions": "12+", "nullableVersions": "12+", "default": "-1null",
 "taggedVersions": "12+", "tag": 0, "ignorable": true,
      "about": "The latestclusterId if known leader epoch". This is used to validate metadata fetches prior to broker registration." },
          { "name": "EndPointReplicaId", "type": "Endpointint32", "versions": "140+",
     "entityType": "brokerId",
       "about": "The endpointreplica thatID canof bethe usedfollower, toof communicate-1 withif thethis leader", "fields": [
   request is from a consumer." },
     ...
    { "name": "HostTopics", "type": "string[]FetchTopic", "versions": "140+",
              "about": "The topics hostnameto fetch." },
   "fields": [
         { "name": "PortTopic", "type": "uint16string", "versions": "14+0-12",
 "entityType": "topicName", "ignorable": true,
          "about": "The port." }
          ]}name of the topic to fetch." },
      {  ]},
        ...
"name": "TopicId", "type": "uuid", "versions": "13+", "ignorable": true,
        ]}
"about": "The unique topic ID"},
      ]}
  ]
}

Handling

Replica that support becoming voters will send both the replica ID and UUID in the Fetch request. The leader will assume that replicas that report both fields are voters or are able to become voters.

There are a few changes to the leader request handling described in KIP-595. The leaders will track the fetch offset for the replica tuple (ID, UUID). This means that replica are unique identified by their ID and UUID. So their state will be tracking using the ID and UUID.

When removing the leader from the voter set, it will remain the leader for that epoch until the RemoveVoterRecord gets committed. This means that the leader needs to allow replicas (voters and observers) to fetch from the leader even if it is not part of the voter set. This also means that if the leader is not part of the voter set it should not include itself when computing the committed offset (also known as the high-watermark).

FetchSnapshot

Request

Version 1 adds the field ReplicaUuid to PartitionSnapshot. If the ReplicaUuid and the ReplicaId fields are populated, the topic partition leader can assume that the replica supports becoming a voter.

Code Block
languagejs
{
  "apiKey": 59,
  { "name": "Partitions", "type": "[]FetchPartition", "versions": "0+",
        "about": "The partitions to fetch.", "fields": [
        { "name": "Partition", "type": "requestint32",
  "listenersversions": ["controller0+"],
  "name": "FetchSnapshotRequest",
        "validVersionsabout": "0-1",
  "flexibleVersions": "0+"The partition index." },
  "fields": [
      { "name": "ClusterIdReplicaUuid", "type": "stringuuid", "versions": "014+", "nullableVersions": "014+", "default": "null",
 "taggedVersions": "0+", "tag": 0,
      "about": "The replica generated UUID. null otherwise." },
        ...
      ]}
    ]}
  ]
}

Response

Version 14 rename LeaderIdAndEpoch to CurrentLeader and adds Endpoint to CurrentLeader.

Code Block
{
  "apiKey": 1,
  clusterId if known, this is used to validate metadata fetches prior to broker
   registration" },
    { "name": "ReplicaId", "type": "int32response",
  "versionsname": "0+FetchResponse",
  "defaultvalidVersions": "0-114",
  "entityTypeflexibleVersions": "brokerId12+",
      "aboutfields": "The[
 replica ID of the follower" }, ...
    { "name": "MaxBytesResponses", "type": "int32[]FetchableTopicResponse", "versions": "0+", "default": "0x7fffffff",
      "about": "The maximum bytes to fetch from all of the snapshots" },
response topics.", "fields": [
      { "name": "TopicsTopic", "type": "[]TopicSnapshotstring", "versions": "0+-12", "ignorable": true, "entityType": "topicName",
        "about": "The topicstopic to fetch", "fields": [name." },
      { "name": "NameTopicId", "type": "stringuuid", "versions": "013+", "entityTypeignorable": "topicName",
        true, "about": "The name ofunique the topic to fetchID" },
      { "name": "Partitions", "type": "[]PartitionSnapshotPartitionData", "versions": "0+",
        "about": "The topic partitions to fetch.", "fields": [
        { ...
        { "name": "PartitionCurrentLeader", "type": "int32CurrentLeader",
          "versions": "012+",
 "taggedVersions": "12+",        "about"tag": 1, "fields": "The[
 partition index" },
        { "name": "ReplicaUuidLeaderId", "type": "uuidint32", "versions": "112+", "default": "-1", "entityType": "nullbrokerId",
            "about": "The replica UUID of the follower" }, 
ID of the current leader or -1 if the leader is unknown."},
          { "name": "CurrentLeaderEpochLeaderEpoch", "type": "int32", "versions": "0+"12+", "default": "-1",
            "about": "The current leader epoch of the partition, -1 for unknownlatest known leader epoch" },
             { "name": "SnapshotIdEndPoint", "type": "SnapshotIdEndpoint", "versions": "014+",
            "about": "The snapshotendpoint that endOffsetcan andbe epochused to fetchcommunicate with the leader", "fields": [
            { "name": "EndOffsetHost", "type": "int64string", "versions": "014+" },
          {  "name": "Epoch", "typeabout": "int32",The hostname."versions": "0+" },
        ]},
        { "name": "PositionPort", "type": "int64uint16", "versions": "014+",
              "about": "The port." }
 byte position within the snapshot to start fetching from" ]}
        ]},
    ]}
  ]
}

Response

Version 1 renames LeaderIdAndEpoch to CurrentLeader and adds Endpoint to CurrentLeader.

    ...
      ]}
    ]}
  ]
}

Handling

Replica that support becoming voters will send both the replica ID and UUID in the Fetch request. The leader will assume that replicas that report both fields are voters or are able to become voters.

There are a few changes to the leader request handling described in KIP-595. The leaders will track the fetch offset for the replica tuple (ID, UUID). This means that replica are unique identified by their ID and UUID. So their state will be tracking using the ID and UUID.

When removing the leader from the voter set, it will remain the leader for that epoch until the RemoveVoterRecord gets committed. This means that the leader needs to allow replicas (voters and observers) to fetch from the leader even if it is not part of the voter set. This also means that if the leader is not part of the voter set it should not include itself when computing the committed offset (also known as the high-watermark).

FetchSnapshot

Request

Version 1 adds the field ReplicaUuid to PartitionSnapshot. If the ReplicaUuid and the ReplicaId fields are populated, the topic partition leader can assume that the replica supports becoming a voter.

Code Block
languagejs
{
  "apiKey": 59,
  "type": "request",
  "listeners": ["controller"],
  "name": "FetchSnapshotRequest",
  "validVersions": "0-1",
  "flexibleVersions": "0+",
  
Code Block
languagejs
{
  "apiKey": 59,
  "type": "response",
  "name": "FetchSnapshotResponse",
  "validVersions": "0-1",
  "flexibleVersions": "0+",
  "fields": [
    { "name": "ThrottleTimeMs", "type": "int32", "versions": "0+", "ignorable": true,
      "about": "The duration in milliseconds for which the request was throttled due to a quota violation, or zero if the request did not violate any quota." },
    { "name": "ErrorCode", "type": "int16", "versions": "0+", "ignorable": false,
      "about": "The top level response error code." },
    { "name": "Topics", "type": "[]TopicSnapshot", "versions": "0+",
      "about": "The topics to fetch.", "fields": [
      { "name": "Name", "type": "string", "versions": "0+", "entityType": "topicName",
        "about": "The name of the topic to fetch." },
      { "name": "Partitions", "type": "[]PartitionSnapshot", "versions": "0+",
        "about": "The partitions to fetch.", "fields": [
        { "name": "Index", "type": "int32", "versions": "0+",
          "about": "The partition index." },
        { "name": "ErrorCode", "type": "int16", "versions": "0+",
          "about": "The error code, or 0 if there was no fetch error." },
        { "name": "SnapshotId", "type": "SnapshotId", "versions": "0+",
          "about": "The snapshot endOffset and epoch fetched",
          "fields": [
          { "name": "EndOffset", "type": "int64", "versions": "0+" },
          { "name": "Epoch", "type": "int32", "versions": "0+" }
        ]},
        { "name": "CurrentLeader", "type": "CurrentLeader",
          "versions": "0+", "taggedVersions": "0+", "tag": 0, "fields": [
          { "name": "LeaderIdClusterId", "type": "int32string", "versions": "0+", "entityTypenullableVersions": "brokerId0+",
 "default": "null", "taggedVersions": "0+", "tag": 0,
      "about": "The ID of the current leader or -1 if the leader is unknown."},clusterId if known, this is used to validate metadata fetches prior to broker
   registration" },
      { "name": "LeaderEpochReplicaId", "type": "int32", "versions": "0+",
 "default": "-1",    "entityType": "brokerId",
      "about": "The replica latestID knownof leaderthe epochfollower" },
          { "name": "EndPointMaxBytes", "type": "Endpointint32", "versions": "10+",
     "default": "0x7fffffff",
       "about": "The endpointmaximum thatbytes canto befetch usedfrom toall communicateof with the leadersnapshots", "fields": [
         },
    { "name": "HostTopics", "type": "string[]TopicSnapshot", "versions": "10+",
              "about": "The hostname." },
      topics to fetch", "fields": [
      { "name": "PortName", "type": "uint16string", "versions": "10+",
      "entityType": "topicName",
        "about": "The port." }
          ]name of the topic to fetch" },
        { "name": "SizePartitions", "type": "int64[]PartitionSnapshot", "versions": "0+",
          "about": "The totalpartitions size of the snapshot." },to fetch", "fields": [
        { "name": "PositionPartition", "type": "int64int32", "versions": "0+",
          "about": "The starting byte position within the snapshot included in the Bytes field."  partition index" },
        { "name": "UnalignedRecordsReplicaUuid", "type": "recordsuuid", "versions": "01+",
          "about"default": "Snapshot data in records format which may not be aligned on an offset boundary" }null",
      ]}
    ]}
  ]
}

Handling

Similar to Fetch, replica that support becoming voters will send both the replica ID and UUID in the FetchSnapshot request. The leader will assume that replicas that report both fields are voters or are able to become voters.

There are a few changes to the leader request handling described in KIP-630. The leaders will track the fetch offset for the replica tuple (ID, UUID). This means that replica are unique identified by their ID and UUID. So their state will be tracking using the ID and UUID.

When removing the leader from the voter set, it will remain the leader for that epoch until the RemoveVoterRecord gets committed. This means that the leader needs to allow replicas (voters and observers) to fetch snapshots from the leader even if it is not part of the voter set.

EndQuorumEpoch

Request

  1. LeaderId was moved out of the topic partition maps
  2. VoterId was added to the request
  3. VoterUuid was added to the Partitions
  4. ReplicaUuid was added to PreferredSuccessors
  5. Allow tagged fields for versions greater than or equal to 1.
 "about": "The replica UUID of the follower" }, 
        { "name": "CurrentLeaderEpoch", "type": "int32", "versions": "0+",
          "about": "The current leader epoch of the partition, -1 for unknown leader epoch" },
        { "name": "SnapshotId", "type": "SnapshotId", "versions": "0+",
          "about": "The snapshot endOffset and epoch to fetch", "fields": [
          { "name": "EndOffset", "type": "int64", "versions": "0+" },
          { "name": "Epoch", "type": "int32", "versions": "0+" }
        ]},
        { "name": "Position", "type": "int64", "versions": "0+",
          "about": "The byte position within the snapshot to start fetching from" }
      ]}
    ]}
  ]
}

Response

Version 1 renames LeaderIdAndEpoch to CurrentLeader and adds Endpoint to CurrentLeader.

Code Block
languagejs
{
  "apiKey": 59,
  "type": "response",
  "name": "FetchSnapshotResponse",
  "validVersions": "0-1",
  "flexibleVersions": "0+",
  "fields": [
Code Block
languagejs
{
  "apiKey": 54,
  "type": "request",
  "listeners": ["controller"],
  "name": "EndQuorumEpochRequest",
  "validVersions": "0-1",
  "flexibleVersions": "1+",
  "fields": [
    { "name": "ClusterId", "type": "string", "versions": "0+",
      "nullableVersions": "0+", "default": "null"},
    { "name": "LeaderId", "type": "int32", "versions": "1+", "entityType": "brokerId",
      "about": "The current leader ID that is resigning." },
    { "name": "VoterIdThrottleTimeMs", "type": "int32", "versions": "10+", "entityTypeignorable": "brokerId"true,
      "about": "The duration in votermilliseconds IDfor ofwhich the receiving replica." }, 
    { "name": "Topics", "type": "[]TopicData", "versions": "0+", "fields": [ request was throttled due to a quota violation, or zero if the request did not violate any quota." },
      { "name": "TopicNameErrorCode", "type": "stringint16", "versions": "0+", "entityTypeignorable": "topicName"false,
        "about": "The topic name top level response error code." },
      { "name": "PartitionsTopics", "type": "[]PartitionDataTopicSnapshot", "versions": "0+", "fields": [
        { "nameabout": "PartitionIndex", "type": "int32"The topics to fetch.", "versionsfields": "0+",[
        {  "aboutname": "The partition index." },
        { "nameName", "type": "VoterUuidstring", "typeversions": "uuid0+", "versionsentityType": "1+topicName",
          "about": "The replica UUIDname of the topic receivingto replicafetch." }, 
        { "name": "LeaderIdPartitions", "type": "int32[]PartitionSnapshot", "versions": "0", "entityType": "brokerId+",
          "about": "The current leader ID that is resigning"},partitions to fetch.", "fields": [
        { "name": "LeaderEpochIndex", "type": "int32", "versions": "0+",
          "about": "The currentpartition epochindex." },
        { "name": "PreferredSuccessorsErrorCode", "type": "[]ReplicaInfoint16", "versions": "0+",
          "about": "AThe sortederror listcode, ofor preferred0 successorsif tothere startwas theno election",fetch error."fields": [},
          { "name": "ReplicaIdSnapshotId", "type": "int32SnapshotId", "versions": "0+", "entityType": "brokerId" },
          { "nameabout": "ReplicaUuid", "type": "uuid", "versions": "1+" }The snapshot endOffset and epoch fetched",
        ]} 
      ]}"fields": [
    ]}
  ]
}

Response

Version 1 is a flexible version and add the tagged field LeaderEndpoint to PartitionData.

Code Block
languagejs
{
  "apiKey": 54,
 { "typename": "responseEndOffset",
  "nametype": "EndQuorumEpochResponseint64",
  "validVersionsversions": "0-1+" },
  "flexibleVersions": "1+",
  "fields": [
    { "name": "ErrorCodeEpoch", "type": "int16int32", "versions": "0+", }
       "about": "The top level error code."},
 ]},
        { "name": "TopicsCurrentLeader", "type": "[]TopicDataCurrentLeader",
          "versions": "0+", "taggedVersions": "0+", "tag": 0, "fields": [
          { "name": "TopicNameLeaderId", "type": "stringint32", "versions": "0+", "entityType": "topicNamebrokerId",
        "about": "The topic name." },
      { "nameabout": "Partitions", "type": "[]PartitionData",
        "versions": "0+", "fields": [
The ID of the current leader or -1 if the leader is unknown."},
          { "name": "PartitionIndexLeaderEpoch", "type": "int32", "versions": "0+",
            "about": "The partition index." latest known leader epoch"},
            { "name": "ErrorCodeEndPoint", "type": "int16Endpoint", "versions": "01+"},
           { "nameabout": "LeaderIdThe endpoint that can be used to communicate with the leader", "typefields": [
            { "name": "int32Host", "versionstype": "0+string", "entityTypeversions": "brokerId1+",
              "about": "The ID of the current leader or -1 if the leader is unknown."},
        hostname." },
            { "name": "LeaderEpochPort", "type": "int32uint16", "versions": "01+",
              "about": "The latest known leader epoch" port." }
          ]},
           { "name": "LeaderEndPointSize", "type": "Endpointint64", "versions": "10+", "taggedVersions": "+1", "tag": 0,
          "about": "The endpointtotal that can be used to communicate withsize of the leadersnapshot.", "fields": [
   },
        { "name": "HostPosition", "type": "stringint64", "versions": "10+",
            "about": "The hostname starting byte position within the snapshot included in the Bytes field."   },
          { "name": "PortUnalignedRecords", "type": "uint16records", "versions": "10+",
            "about": "The port.Snapshot data in records format which may not be aligned on an offset boundary" }
        ]}
    ]}
  ]}
    ]}
  ]
}

Handling

This request will be handle as described in KIP-595 with the following additional errors:

...


}

Handling

Similar to Fetch, replica that support becoming voters will send both the replica ID and UUID in the FetchSnapshot request. The leader will assume that replicas that report both fields are voters or are able to become voters.

There are a few changes to the leader request handling described in KIP-630. The leaders will track the fetch offset for the replica tuple (ID, UUID). This means that replica are unique identified by their ID and UUID. So their state will be tracking using the ID and UUID.

When removing the leader from the voter set, it will remain the leader for that epoch until the RemoveVoterRecord gets committed. This means that the leader needs to allow replicas (voters and observers) to fetch snapshots from the leader even if it is not part of the voter set

...

.

DescribeQuorum

The version of the request is increase and the fields remain unchanged.

...