Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
a8bdc7b
KAFKA-14274 [6, 7]: Introduction of fetch request manager
kirktrue Sep 19, 2023
7ab56f2
Reverted change to make FetchCollector.collectFetch() not take a Dese…
kirktrue Sep 19, 2023
772ff2e
KAFKA-14274 [6, 7]: Introduction of fetch request manager
kirktrue Sep 19, 2023
a30ac4e
Reverted change to make FetchCollector.collectFetch() not take a Dese…
kirktrue Sep 19, 2023
72b6b27
Post-rebase clean up
kirktrue Sep 22, 2023
ba9f0ff
Merge branch 'KAFKA-14274-3-introduce-fetch-request-manager-take-2' o…
kirktrue Sep 22, 2023
7c8b945
Update NetworkClientDelegate.java
kirktrue Sep 22, 2023
59d0daf
Minor clean up and refactoring based on first pass of reviews
kirktrue Sep 23, 2023
5eef0f7
Medium-sized refactor of the queue processing
kirktrue Sep 26, 2023
0457117
Merge branch 'trunk' into KAFKA-14274-3-introduce-fetch-request-manag…
kirktrue Sep 26, 2023
1e18f98
Changes to PrototypeAsyncConsumer.close()
kirktrue Sep 26, 2023
4a9cdd0
Updates to the fetch results/buffering process
kirktrue Sep 26, 2023
c873463
Updates for background event handler
kirktrue Sep 26, 2023
e8b990f
Minor refactoring for the event processor callbacks
kirktrue Sep 26, 2023
731e716
Added comment to explain a case in DefaultBackgroundThread.wakeup()
kirktrue Sep 26, 2023
3f92079
Closing the fetch sessions
kirktrue Sep 28, 2023
e08d01a
Minor logic change for assignFromUserNoId
kirktrue Oct 3, 2023
d7c4d0c
Minor logic change for assignFromUserNoId (from FetchRequestManagerTest)
kirktrue Oct 3, 2023
6ffb7ec
Removed unnecessary references to "this" in fetcher tests
kirktrue Oct 3, 2023
81c0c7e
Renamed FetchRequestManagerTest's consumerClient to networkClientDele…
kirktrue Oct 3, 2023
7674304
Removed FetchRequestManagerTest's oldConsumerClient
kirktrue Oct 3, 2023
0cbb8d2
Updated comment placement in old and new fetcher tests
kirktrue Oct 3, 2023
9c7b4c4
Added documentation to RequestManager methods and referenced from Fet…
kirktrue Oct 3, 2023
65197a1
Refactored AbstractFetch to make fetch request maps more succinct
kirktrue Oct 3, 2023
5387b7f
Removed unnecessary "this" references.
kirktrue Oct 4, 2023
8490681
Minor formatting change in beginningOrEndOffset
kirktrue Oct 4, 2023
4e463d2
Revised usage of Timer in DefaultBackgroundThread.runAtClose()
kirktrue Oct 4, 2023
d3e920d
Got fed up and changed DefaultBackgroundThread to ConsumerNetworkThread
kirktrue Oct 4, 2023
60470ed
Asserting ConsumerNetworkThread is not closed on each call to runOnce()
kirktrue Oct 4, 2023
6c1004f
Clean up of outdated comments for BackgroundEventProcessor.process()
kirktrue Oct 4, 2023
8497558
Clean up of logging, but a lot of other refactoring to reduce boilerp…
kirktrue Oct 4, 2023
6338733
Removed now unneeded BackgroundEventHandler from FetchRequestManager
kirktrue Oct 4, 2023
634e15b
Turned down the logging level in a couple of places
kirktrue Oct 5, 2023
5f9aa58
Removed comment about wakeups from poll() (filed KAFKA-15555 to handle)
kirktrue Oct 5, 2023
193af82
Fixed comment in assign() method
kirktrue Oct 5, 2023
cda5741
Made FetchBuffer thread safe so that it can be shared by application …
kirktrue Oct 6, 2023
0d56cac
Minor: removed unnecessarily qualified reference to object from withi…
kirktrue Oct 7, 2023
f4fac21
Merge remote-tracking branch 'upstream/trunk' into KAFKA-14274-3-intr…
kirktrue Oct 9, 2023
17458c4
Resolving merge conflicts with changes to trunk
kirktrue Oct 9, 2023
281f28c
Removed assertion from ConsumerNetworkThread.runOnce to avoid logging
kirktrue Oct 9, 2023
15738bd
Updated the fetch response handler method names for clarity
kirktrue Oct 10, 2023
24e014f
ApplicationEventProcessor will now NOT throw errors on event processi…
kirktrue Oct 10, 2023
2eaca7e
Removed redundant tests from ConsumerNetworkThreadTest
kirktrue Oct 10, 2023
d2ab01e
Now issuing both the poll() and pollOnClose() network I/O on the Cons…
kirktrue Oct 10, 2023
19327fa
Fixed minor whitespace checkstyle violation in ConsumerNetworkThreadTest
kirktrue Oct 10, 2023
621fc7d
Fixed typo in RequestManager comment
kirktrue Oct 10, 2023
bc3102f
Merge remote-tracking branch 'upstream/trunk' into KAFKA-14274-3-intr…
kirktrue Oct 13, 2023
5a80371
Comments change to remove close() method in testFetcherCloseClosesFet…
kirktrue Oct 13, 2023
2ba9e85
Removed superfluous poll() from testFetcherCloseClosesFetchSessionsIn…
kirktrue Oct 13, 2023
627624c
Updated method names in FetcherTest and FetchRequestManagerTest
kirktrue Oct 13, 2023
6ebd657
Changed locally-scoped "records" to "testRecords" to avoid naming col…
kirktrue Oct 13, 2023
e971901
Grammar fixes for comments in fetch tests
kirktrue Oct 13, 2023
97d833e
Removed unnecessary fetchRecords call from testPartialFetchWithPaused…
kirktrue Oct 13, 2023
5629d2c
Refactoring to use parameterized test for different fetch response er…
kirktrue Oct 13, 2023
913fc8b
Added check for no pending requests in testEpochSetInFetchRequest
kirktrue Oct 13, 2023
e4c416c
Added clarifying comments to testFetchedRecordsAfterSeek
kirktrue Oct 13, 2023
dd95661
Updated fetch tests to use fetchRecordsInto utility method to reduce …
kirktrue Oct 13, 2023
b752bf8
Fixed typo in comments
kirktrue Oct 13, 2023
8458f2c
Renamed and swapped 'expected' vs. 'actual' comparison in testMultipl…
kirktrue Oct 13, 2023
7e39a74
Changed testReturnAbortedTransactionsinUncommittedMode() to testRetur…
kirktrue Oct 13, 2023
2bd3635
Grammar/typo fix
kirktrue Oct 13, 2023
cd0e9ae
Moved comment in testPreferredReadReplicaOffsetError closer to applic…
kirktrue Oct 13, 2023
b18720f
Removed FetchEvent and added wakeup() method to ApplicationEventHandler
kirktrue Oct 14, 2023
f6093d6
Updates to change references to method namews
kirktrue Oct 16, 2023
589bcc8
Removed outdated comment in testUnauthorizedTopic()
kirktrue Oct 16, 2023
e9d2bef
Test method name changed for clarity
kirktrue Oct 16, 2023
44e7789
Removed unnecessarily comment from FetchRequestManagerTest.testFetche…
kirktrue Oct 19, 2023
1eaad84
Updated variable name in FetchRequestManagerTest.testFetcherCloseClos…
kirktrue Oct 19, 2023
9483363
On close, make the application thread wait for the network thread to …
kirktrue Oct 19, 2023
99a65ec
Handle previously cached errors from getOffsetResetTimestamp
kirktrue Oct 20, 2023
8372505
Updated wakeup() to be invoked only after receiving a non-empty Fetch
kirktrue Oct 20, 2023
fb4d1c2
Fixed misleading comment in FetcherTest/FetchRequestManagerTest testF…
kirktrue Oct 20, 2023
f40d4d2
Making NetworkClientDelegate constructor call another to eliminate re…
kirktrue Oct 20, 2023
56d0b40
Merge branch 'trunk' into KAFKA-14274-3-introduce-fetch-request-manag…
kirktrue Oct 20, 2023
13cb3b6
Ensure wakeupNetworkThread() is called even on empty Fetch results
kirktrue Oct 20, 2023
9525fca
Changed OffsetFetcherUtils.offsetResetStrategyTimestamp to throw a No…
kirktrue Oct 20, 2023
c5d5fc6
Renamed refreshCommittedOffsetsIfNeeded to initWithCommittedOffsetsIf…
kirktrue Oct 21, 2023
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
4 changes: 4 additions & 0 deletions checkstyle/import-control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@

<subpackage name="consumer">
<allow pkg="org.apache.kafka.clients.consumer" />

Comment thread
kirktrue marked this conversation as resolved.
<subpackage name="internals">
<allow pkg="org.apache.kafka.clients" />
</subpackage>
</subpackage>

<subpackage name="producer">
Expand Down
12 changes: 7 additions & 5 deletions checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@
files="AbstractRequest.java"/>
<suppress checks="ClassFanOutComplexity"
files="AbstractResponse.java"/>
<suppress checks="ClassFanOutComplexity"
files="PrototypeAsyncConsumer.java"/>

<suppress checks="MethodLength"
files="(KerberosLogin|RequestResponseTest|ConnectMetricsRegistry|KafkaConsumer|AbstractStickyAssignor).java"/>

<suppress checks="ParameterNumber"
files="(NetworkClient|FieldSpec|KafkaRaftClient).java"/>
<suppress checks="ParameterNumber"
files="(KafkaConsumer|ConsumerCoordinator).java"/>
files="(KafkaConsumer|PrototypeAsyncConsumer|ConsumerCoordinator).java"/>
<suppress checks="ParameterNumber"
files="(RecordAccumulator|Sender).java"/>
<suppress checks="ParameterNumber"
Expand All @@ -79,7 +81,7 @@
files="MemoryRecordsBuilder.java"/>

<suppress checks="ClassDataAbstractionCoupling"
files="(KafkaConsumer|ConsumerCoordinator|AbstractFetch|KafkaProducer|AbstractRequest|AbstractResponse|TransactionManager|Admin|KafkaAdminClient|MockAdminClient|KafkaRaftClient|KafkaRaftClientTest).java"/>
files="(KafkaConsumer|PrototypeAsyncConsumer|ConsumerCoordinator|AbstractFetch|KafkaProducer|AbstractRequest|AbstractResponse|TransactionManager|Admin|KafkaAdminClient|MockAdminClient|KafkaRaftClient|KafkaRaftClientTest).java"/>
<suppress checks="ClassDataAbstractionCoupling"
files="(Errors|SaslAuthenticatorTest|AgentTest|CoordinatorTest).java"/>

Expand Down Expand Up @@ -108,10 +110,10 @@

<!-- Clients tests -->
<suppress checks="ClassDataAbstractionCoupling"
files="(Sender|Fetcher|OffsetFetcher|KafkaConsumer|Metrics|RequestResponse|TransactionManager|KafkaAdminClient|Message|KafkaProducer)Test.java"/>
files="(Sender|Fetcher|FetchRequestManager|OffsetFetcher|KafkaConsumer|PrototypeAsyncConsumer|Metrics|RequestResponse|TransactionManager|KafkaAdminClient|Message|KafkaProducer)Test.java"/>

<suppress checks="ClassFanOutComplexity"
files="(ConsumerCoordinator|KafkaConsumer|RequestResponse|Fetcher|KafkaAdminClient|Message|KafkaProducer)Test.java"/>
files="(ConsumerCoordinator|KafkaConsumer|RequestResponse|Fetcher|FetchRequestManager|KafkaAdminClient|Message|KafkaProducer)Test.java"/>

<suppress checks="ClassFanOutComplexity"
files="MockAdminClient.java"/>
Expand All @@ -120,7 +122,7 @@
files="(OffsetFetcher|RequestResponse)Test.java"/>

<suppress checks="JavaNCSS"
files="RequestResponseTest.java|FetcherTest.java|KafkaAdminClientTest.java"/>
files="RequestResponseTest.java|FetcherTest.java|FetchRequestManagerTest.java|KafkaAdminClientTest.java"/>

<suppress checks="NPathComplexity"
files="MemoryRecordsTest|MetricsTest|RequestResponseTest|TestSslUtils|AclAuthorizerBenchmark"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -752,13 +752,14 @@ public KafkaConsumer(Map<String, Object> configs,
config.getBoolean(ConsumerConfig.THROW_ON_FETCH_STABLE_OFFSET_UNSUPPORTED),
config.getString(ConsumerConfig.CLIENT_RACK_CONFIG));
}
FetchConfig<K, V> fetchConfig = createFetchConfig(config, this.deserializers);
FetchConfig fetchConfig = createFetchConfig(config);
this.fetcher = new Fetcher<>(
logContext,
this.client,
this.metadata,
this.subscriptions,
fetchConfig,
this.deserializers,
fetchMetricsManager,
this.time);
this.offsetFetcher = new OffsetFetcher(logContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

import org.apache.kafka.clients.ClientResponse;
import org.apache.kafka.clients.FetchSessionHandler;
import org.apache.kafka.clients.KafkaClient;
import org.apache.kafka.clients.NetworkClientUtils;
import org.apache.kafka.common.Cluster;
import org.apache.kafka.common.Node;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.Uuid;
import org.apache.kafka.common.errors.AuthenticationException;
import org.apache.kafka.common.internals.IdempotentCloser;
import org.apache.kafka.common.message.FetchResponseData;
import org.apache.kafka.common.protocol.ApiKeys;
Expand All @@ -37,11 +40,9 @@
import org.slf4j.helpers.MessageFormatter;

import java.io.Closeable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
Expand All @@ -51,17 +52,14 @@

/**
* {@code AbstractFetch} represents the basic state and logic for record fetching processing.
* @param <K> Type for the message key
* @param <V> Type for the message value
*/
public abstract class AbstractFetch<K, V> implements Closeable {
public abstract class AbstractFetch implements Closeable {

private final Logger log;
protected final LogContext logContext;
protected final ConsumerNetworkClient client;
protected final ConsumerMetadata metadata;
protected final SubscriptionState subscriptions;
protected final FetchConfig<K, V> fetchConfig;
protected final FetchConfig fetchConfig;
protected final Time time;
protected final FetchMetricsManager metricsManager;
protected final FetchBuffer fetchBuffer;
Expand All @@ -72,15 +70,13 @@ public abstract class AbstractFetch<K, V> implements Closeable {
private final Map<Integer, FetchSessionHandler> sessionHandlers;

public AbstractFetch(final LogContext logContext,
final ConsumerNetworkClient client,
final ConsumerMetadata metadata,
final SubscriptionState subscriptions,
final FetchConfig<K, V> fetchConfig,
final FetchConfig fetchConfig,
final FetchMetricsManager metricsManager,
final Time time) {
this.log = logContext.logger(AbstractFetch.class);
this.logContext = logContext;
this.client = client;
this.metadata = metadata;
this.subscriptions = subscriptions;
this.fetchConfig = fetchConfig;
Expand All @@ -92,6 +88,23 @@ public AbstractFetch(final LogContext logContext,
this.time = time;
}

/**
* Check if the node is disconnected and unavailable for immediate reconnection (i.e. if it is in
* reconnect backoff window following the disconnect).
*
* @param node {@link Node} to check for availability
* @see NetworkClientUtils#isUnavailable(KafkaClient, Node, Time)
*/
protected abstract boolean isUnavailable(Node node);
Comment thread
kirktrue marked this conversation as resolved.

/**
* Checks for an authentication error on a given node and throws the exception if it exists.
*
* @param node {@link Node} to check for a previous {@link AuthenticationException}; if found it is thrown
* @see NetworkClientUtils#maybeThrowAuthFailure(KafkaClient, Node)
*/
protected abstract void maybeThrowAuthFailure(Node node);

/**
* Return whether we have any completed fetches pending return to the user. This method is thread-safe. Has
* visibility for testing.
Expand Down Expand Up @@ -317,7 +330,7 @@ Node selectReadReplica(final TopicPartition partition, final Node leaderReplica,
}
}

private Map<Node, FetchSessionHandler.FetchRequestData> prepareCloseFetchSessionRequests() {
protected Map<Node, FetchSessionHandler.FetchRequestData> prepareCloseFetchSessionRequests() {
final Cluster cluster = metadata.fetch();
Map<Node, FetchSessionHandler.Builder> fetchable = new LinkedHashMap<>();

Expand All @@ -330,7 +343,7 @@ private Map<Node, FetchSessionHandler.FetchRequestData> prepareCloseFetchSession
// skip sending the close request.
final Node fetchTarget = cluster.nodeById(fetchTargetNodeId);

if (fetchTarget == null || client.isUnavailable(fetchTarget)) {
if (fetchTarget == null || isUnavailable(fetchTarget)) {
Comment thread
kirktrue marked this conversation as resolved.
log.debug("Skip sending close session request to broker {} since it is not reachable", fetchTarget);
return;
}
Expand Down Expand Up @@ -377,8 +390,8 @@ protected Map<Node, FetchSessionHandler.FetchRequestData> prepareFetchRequests()
// Use the preferred read replica if set, otherwise the partition's leader
Node node = selectReadReplica(partition, leaderOpt.get(), currentTimeMs);

if (client.isUnavailable(node)) {
client.maybeThrowAuthFailure(node);
if (isUnavailable(node)) {
maybeThrowAuthFailure(node);

// If we try to send during the reconnect backoff window, then the request is just
// going to be failed anyway before being sent, so skip sending the request for now
Expand Down Expand Up @@ -412,46 +425,6 @@ protected Map<Node, FetchSessionHandler.FetchRequestData> prepareFetchRequests()
return reqs;
}

protected void maybeCloseFetchSessions(final Timer timer) {
final List<RequestFuture<ClientResponse>> requestFutures = new ArrayList<>();
Map<Node, FetchSessionHandler.FetchRequestData> fetchRequestMap = prepareCloseFetchSessionRequests();

for (Map.Entry<Node, FetchSessionHandler.FetchRequestData> entry : fetchRequestMap.entrySet()) {
final Node fetchTarget = entry.getKey();
final FetchSessionHandler.FetchRequestData data = entry.getValue();
final FetchRequest.Builder request = createFetchRequest(fetchTarget, data);
final RequestFuture<ClientResponse> responseFuture = client.send(fetchTarget, request);

responseFuture.addListener(new RequestFutureListener<ClientResponse>() {
@Override
public void onSuccess(ClientResponse value) {
handleCloseFetchSessionResponse(fetchTarget, data);
}

@Override
public void onFailure(RuntimeException e) {
handleCloseFetchSessionResponse(fetchTarget, data, e);
}
});

requestFutures.add(responseFuture);
}

// Poll to ensure that request has been written to the socket. Wait until either the timer has expired or until
// all requests have received a response.
while (timer.notExpired() && !requestFutures.stream().allMatch(RequestFuture::isDone)) {
client.poll(timer, null, true);
}

if (!requestFutures.stream().allMatch(RequestFuture::isDone)) {
// we ran out of time before completing all futures. It is ok since we don't want to block the shutdown
// here.
log.debug("All requests couldn't be sent in the specific timeout period {}ms. " +
"This may result in unnecessary fetch sessions at the broker. Consider increasing the timeout passed for " +
"KafkaConsumer.close(Duration timeout)", timer.timeoutMs());
}
}

// Visible for testing
protected FetchSessionHandler sessionHandler(int node) {
return sessionHandlers.get(node);
Expand All @@ -467,8 +440,6 @@ protected FetchSessionHandler sessionHandler(int node) {
// Visible for testing
protected void closeInternal(Timer timer) {
// we do not need to re-enable wake-ups since we are closing already
client.disableWakeups();
maybeCloseFetchSessions(timer);
Utils.closeQuietly(fetchBuffer, "fetchBuffer");
Utils.closeQuietly(decompressionBufferSupplier, "decompressionBufferSupplier");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.kafka.clients.consumer.internals;

import java.util.function.Supplier;

/**
* Simple {@link Supplier} that caches the initial creation of the object and stores it for later calls
* to {@link #get()}.
*
* <p/>
*
* <em>Note</em>: this class is not thread safe! Use only in contexts which are designed/guaranteed to be
* single-threaded.
*/
public abstract class CachedSupplier<T> implements Supplier<T> {

private T result;

protected abstract T create();

@Override
public T get() {
if (result == null)
result = create();

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
/**
* {@link CompletedFetch} represents a {@link RecordBatch batch} of {@link Record records} that was returned from the
* broker via a {@link FetchRequest}. It contains logic to maintain state between calls to
* {@link #fetchRecords(FetchConfig, int)}.
* {@link #fetchRecords(FetchConfig, Deserializers, int)}.
*/
public class CompletedFetch {

Expand Down Expand Up @@ -135,7 +135,8 @@ void recordAggregatedMetrics(int bytes, int records) {
/**
* Draining a {@link CompletedFetch} will signal that the data has been consumed and the underlying resources
* are closed. This is somewhat analogous to {@link Closeable#close() closing}, though no error will result if a
* caller invokes {@link #fetchRecords(FetchConfig, int)}; an empty {@link List list} will be returned instead.
* caller invokes {@link #fetchRecords(FetchConfig, Deserializers, int)}; an empty {@link List list} will be
Comment thread
junrao marked this conversation as resolved.
* returned instead.
*/
void drain() {
if (!isConsumed) {
Expand All @@ -151,7 +152,7 @@ void drain() {
}
}

private <K, V> void maybeEnsureValid(FetchConfig<K, V> fetchConfig, RecordBatch batch) {
private void maybeEnsureValid(FetchConfig fetchConfig, RecordBatch batch) {
if (fetchConfig.checkCrcs && batch.magic() >= RecordBatch.MAGIC_VALUE_V2) {
try {
batch.ensureValid();
Expand All @@ -162,7 +163,7 @@ private <K, V> void maybeEnsureValid(FetchConfig<K, V> fetchConfig, RecordBatch
}
}

private <K, V> void maybeEnsureValid(FetchConfig<K, V> fetchConfig, Record record) {
private void maybeEnsureValid(FetchConfig fetchConfig, Record record) {
if (fetchConfig.checkCrcs) {
try {
record.ensureValid();
Expand All @@ -180,7 +181,7 @@ private void maybeCloseRecordStream() {
}
}

private <K, V> Record nextFetchedRecord(FetchConfig<K, V> fetchConfig) {
private Record nextFetchedRecord(FetchConfig fetchConfig) {
while (true) {
if (records == null || !records.hasNext()) {
maybeCloseRecordStream();
Expand Down Expand Up @@ -249,7 +250,9 @@ private <K, V> Record nextFetchedRecord(FetchConfig<K, V> fetchConfig) {
* @param maxRecords The number of records to return; the number returned may be {@code 0 <= maxRecords}
* @return {@link ConsumerRecord Consumer records}
*/
<K, V> List<ConsumerRecord<K, V>> fetchRecords(FetchConfig<K, V> fetchConfig, int maxRecords) {
<K, V> List<ConsumerRecord<K, V>> fetchRecords(FetchConfig fetchConfig,
Deserializers<K, V> deserializers,
Comment thread
kirktrue marked this conversation as resolved.
int maxRecords) {
// Error when fetching the next record before deserialization.
if (corruptLastRecord)
throw new KafkaException("Received exception when fetching the next record from " + partition
Expand All @@ -276,7 +279,7 @@ <K, V> List<ConsumerRecord<K, V>> fetchRecords(FetchConfig<K, V> fetchConfig, in

Optional<Integer> leaderEpoch = maybeLeaderEpoch(currentBatch.partitionLeaderEpoch());
TimestampType timestampType = currentBatch.timestampType();
ConsumerRecord<K, V> record = parseRecord(fetchConfig, partition, leaderEpoch, timestampType, lastRecord);
ConsumerRecord<K, V> record = parseRecord(deserializers, partition, leaderEpoch, timestampType, lastRecord);
records.add(record);
recordsRead++;
bytesRead += lastRecord.sizeInBytes();
Expand All @@ -302,7 +305,7 @@ <K, V> List<ConsumerRecord<K, V>> fetchRecords(FetchConfig<K, V> fetchConfig, in
/**
* Parse the record entry, deserializing the key / value fields if necessary
*/
<K, V> ConsumerRecord<K, V> parseRecord(FetchConfig<K, V> fetchConfig,
<K, V> ConsumerRecord<K, V> parseRecord(Deserializers<K, V> deserializers,
TopicPartition partition,
Optional<Integer> leaderEpoch,
TimestampType timestampType,
Expand All @@ -312,16 +315,16 @@ <K, V> ConsumerRecord<K, V> parseRecord(FetchConfig<K, V> fetchConfig,
long timestamp = record.timestamp();
Headers headers = new RecordHeaders(record.headers());
ByteBuffer keyBytes = record.key();
K key = keyBytes == null ? null : fetchConfig.deserializers.keyDeserializer.deserialize(partition.topic(), headers, keyBytes);
K key = keyBytes == null ? null : deserializers.keyDeserializer.deserialize(partition.topic(), headers, keyBytes);
ByteBuffer valueBytes = record.value();
V value = valueBytes == null ? null : fetchConfig.deserializers.valueDeserializer.deserialize(partition.topic(), headers, valueBytes);
V value = valueBytes == null ? null : deserializers.valueDeserializer.deserialize(partition.topic(), headers, valueBytes);
return new ConsumerRecord<>(partition.topic(), partition.partition(), offset,
timestamp, timestampType,
keyBytes == null ? ConsumerRecord.NULL_SIZE : keyBytes.remaining(),
valueBytes == null ? ConsumerRecord.NULL_SIZE : valueBytes.remaining(),
key, value, headers, leaderEpoch);
} catch (RuntimeException e) {
log.error("Deserializers with error: {}", fetchConfig.deserializers);
log.error("Deserializers with error: {}", deserializers);
throw new RecordDeserializationException(partition, record.offset(),
"Error deserializing key/value for partition " + partition +
" at offset " + record.offset() + ". If needed, please seek past the record to continue consumption.", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,9 @@ public static FetchMetricsManager createFetchMetricsManager(Metrics metrics) {
return new FetchMetricsManager(metrics, metricsRegistry);
}

public static <K, V> FetchConfig<K, V> createFetchConfig(ConsumerConfig config,
Deserializers<K, V> deserializers) {
public static FetchConfig createFetchConfig(ConsumerConfig config) {
IsolationLevel isolationLevel = configuredIsolationLevel(config);
return new FetchConfig<>(config, deserializers, isolationLevel);
return new FetchConfig(config, isolationLevel);
}

@SuppressWarnings("unchecked")
Expand Down
Loading