Skip to content

KAFKA-14960: TopicMetadata request manager#14386

Merged
junrao merged 32 commits into
apache:trunkfrom
philipnee:cherry-pick-topic-metadata
Sep 21, 2023
Merged

KAFKA-14960: TopicMetadata request manager#14386
junrao merged 32 commits into
apache:trunkfrom
philipnee:cherry-pick-topic-metadata

Conversation

@philipnee

Copy link
Copy Markdown
Contributor

TopicMetadataRequestManager is responsible for sending topic metadata requests. The manager manages API requests and build the request accordingly. All topic metadata requests are chained, if requesting the same topic, to avoid sending requests repeatedly.

philipnee and others added 24 commits September 11, 2023 07:51
TopicMetadataRequestManager implementation

---------

Co-authored-by: Lianet Magrans <lmagrans@confluent.io>
it's in a state that all tests are passing

rebase
…nly closed once

Added IdempotentCloser to ensure resources are only closed once. While this class is broadly useful, it will be constrained to consumer internals until a later date.
TopicMetadataRequestManager implementation

---------

Co-authored-by: Lianet Magrans <lmagrans@confluent.io>
it's in a state that all tests are passing

rebase
…nly closed once

Added IdempotentCloser to ensure resources are only closed once. While this class is broadly useful, it will be constrained to consumer internals until a later date.
…es are only closed once"

This reverts commit 76d5c96.
Update CommitRequestManager.java

clean up

clean up

remove idempotent references
TopicMetadataRequestManager implementation

---------

Co-authored-by: Lianet Magrans <lmagrans@confluent.io>
it's in a state that all tests are passing

rebase
…nly closed once

Added IdempotentCloser to ensure resources are only closed once. While this class is broadly useful, it will be constrained to consumer internals until a later date.
TopicMetadataRequestManager implementation

---------

Co-authored-by: Lianet Magrans <lmagrans@confluent.io>
it's in a state that all tests are passing

rebase
…nly closed once

Added IdempotentCloser to ensure resources are only closed once. While this class is broadly useful, it will be constrained to consumer internals until a later date.
…es are only closed once"

This reverts commit 76d5c96.
Update CommitRequestManager.java

clean up

clean up

remove idempotent references
@philipnee
philipnee marked this pull request as ready for review September 13, 2023 19:57
@philipnee philipnee added the ctr Consumer Threading Refactor (KIP-848) label Sep 13, 2023

@junrao junrao left a comment

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.

@philipnee : Thanks for the PR. Made a pass of non-testing files. Left a few comments.


/**
* Poll for the {@link OffsetFetchRequest} and {@link OffsetCommitRequest} request if there's any. The function will
* Poll for the {@link OffsetFetchRequest} and {@link org.apache.kafka.common.requests.OffsetCommitRequest} request if there's any. The function will

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.

Do we need to spell out the package name for OffsetCommitRequest? It doesn't seem this is done consistently.

}

OffsetCommitRequest.Builder builder = new OffsetCommitRequest.Builder(
org.apache.kafka.common.requests.OffsetCommitRequest.Builder builder = new org.apache.kafka.common.requests.OffsetCommitRequest.Builder(

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.

Could we import the package?


public String topic() {
return topic;
}

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.

Do we need to add toString, equals and hashcode?

/**
* <p>
* Manages the state of topic metadata requests. This manager returns a
* {@link org.apache.kafka.clients.consumer.internals.NetworkClientDelegate.PollResult} when a request is ready to

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.

Do we need to spell out the package name?

* be sent. Specifically, this manager handles the following user API calls:
* </p>
* <ul>
* <li>listOffsets</li>

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.

Is this true? OffsetsRequestManager says it handles listOffsets.

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.

🤦 - listTopics() instead.

throw new RuntimeException(exception.get());
this.offsets = Collections.unmodifiableMap(offsets);

for (OffsetAndMetadata offsetAndMetadata : offsets.values()) {

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.

This is an existing issue. Could we change toString to include the fields in the parent class? Do we need to add equals and hashcode for consistency?

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.

There are quite a few events out there that need to be refactored if we do it this way. Would it be ok for you to skip this for now and I will post a MINOR patch to address after this is closed?

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.

If your PR goes in before mine, you can make a comment and I'll add the toString changes into mine.

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.

Yes, it's fine to clean this up separately.

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.

@junrao - per your request. Here's the patch to address your comment: #14391

return new NetworkClientDelegate.PollResult(Long.MAX_VALUE, Collections.emptyList());
}

pendingRequests.inflightOffsetFetches.forEach(System.out::println);

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.

Is this intended?

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.

🤦

public final GroupState.Generation requestedGeneration;
public CompletableFuture<Map<TopicPartition, OffsetAndMetadata>> future;

CompletableFuture<Map<TopicPartition, OffsetAndMetadata>> future;

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.

Could this be private?

List<OffsetFetchRequestState> inflightOffsetFetches = new ArrayList<>();

public boolean hasUnsentRequests() {
boolean hasUnsentRequests() {

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.

Could this be private? Ditto below.

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.

Sorry - I left out commit. Fixing those obvious mistakes right away.

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.

Sorry - leaving this protected as it is used in one of the test to verify there's no more unsent request.

this.requestBuilder = requestBuilder;
this.node = node;
this.handler = handler;
final BiConsumer<ClientResponse, Throwable> callback) {

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.

This constructor seems unused?

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.

I think it is according to my IDE. I think it is used in CommitRequestManager (line 219 and 256) and TopicMetadataRequestManger (line 145)

@philipnee

Copy link
Copy Markdown
Contributor Author

Hey @junrao - Addressed your comments. I'm holding off on your request for Could we change toString to include the fields in the parent class? as I think it would be easier if I do that consistently for all other CompletableApplicationEvents. WDYT?

CompletableFuture<Map<String, List<PartitionInfo>>> future;

public TopicMetadataRequestState(final LogContext logContext,
final Optional<String> topic,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

indentation

private MockTime time;
private TopicMetadataRequestManager topicMetadataRequestManager;

private Properties props;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is only used in the setup so no need to keep it at the class level

@junrao junrao left a comment

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.

@philipnee : Thanks for the updated PR. Made a pass of all files. A few more comments.

* </p>
* <ul>
* <li>listOffsets</li>
* <li>partitionsFor</li>

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.

Yes, this is fine.

future.complete(res);
inflightRequests.remove(topic);
} catch (RetriableException e) {
if (e instanceof TimeoutException) {

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.

This captures the case when a single request takes long on the broker and times out. However, a separate case is that individual request returns on time but with other RetriableException. In that case, TopicMetadataRequestManager will not clean up inflightRequests even when the client request has timed out.

@philipnee philipnee Sep 15, 2023

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.

Hey @junrao - Sorry for writing such a long reply - I really need to brush up my memory about the network module as well as the TopicMetadataRequest...

In the current code I think the following is how responses should be handled.

For the case of hard failure that the callback receives a non-null exception:
We should remove the inflight request for all non-retriable and TimeoutException because we need to fail the user requests and topic the retry. However, we should continue to retry for RetriableException until timer runs out.

For the case of soft failure (the server respond with an error code), it seems like the right thing to do is to continue to retry except for the non-retriable exception.

It is worth noting that: If the request timed-out (API level timeout), callback is completed with TimeoutException hard failure (in the network delegate module), which should eventually causes the exception to be purged from the inflight request as mentioned above.

To your question: if the responses include a retriable exception, I believe the right thing to do is to continue to retry until the timer runs out.

In fact - it seems like if (e instanceof TimeoutException) (that I added in the last commit) is actually incorrect. Because it is a RetriableException at it should be retried per:

if (error.exception() instanceof RetriableException)
                            shouldRetry = true;

What's missing here is handling the hard RetriableException and TimeoutException. I will fix the code and add test cases to cover the scenarios above.

throw new RuntimeException(exception.get());
this.offsets = Collections.unmodifiableMap(offsets);

for (OffsetAndMetadata offsetAndMetadata : offsets.values()) {

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.

Yes, it's fine to clean this up separately.

verify(commitManager, times(1)).updateAutoCommitTimer(currentTimeMs);
verify(commitManager, times(1)).maybeAutoCommit(offset);

backgroundThread.close();

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.

It seems that we close backgroundThread in other cases?

try {
future.get();
} catch (Throwable e) {
System.out.println(e.getMessage());

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.

In general, we should use logging instead of print.

Address PR

Update TopicMetadataRequestManager.java
handleException(exception, responseTimeMs);
return;
}
handleResponse(response, responseTimeMs);

@lianetm lianetm Sep 15, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems that the exception handling logic here ends up in 2 places. Apart from the initial handleException, this handleResponse could be as well end up handling exceptions, in a very similar way (catch block on handleResponse vs the handleException). If we prefer to keep them separated because of the "retryOnTimeout" part, which seems to be what makes them different, it would be helpful maybe to add a comment to describe that

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.

thanks, @lianetm - Do you think it would be clearer to keep them in 1 place? The intention was to handle hard failures in handleException and soft failures (i.e. returning an error code) in handleResponse.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it would be clearer and better to maintain/troubleshoot if error handling is in one place. Maybe having a single handleException(final Throwable exception, final long responseTimeMs, boolean retryOnTimeout), called in both cases:

if (exception != null) {
                // Handle hard errors
                handleException(exception, responseTimeMs, false);
                ...
}
...
catch (Exception e) {
                // Handle soft errors
                handleException(e, responseTimeMs, true);
}

@junrao junrao left a comment

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.

@philipnee : Thanks for the updated PR. A few more comments.


private void processResponseOrException(final ClientResponse response,
final Throwable exception) {
long responseTimeMs = System.currentTimeMillis();

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.

Could we pass in currentTime from the caller?

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.

Hi Jun - understood making repeated system calls is bad. However - we do need to get the time when the response is received, so this is kind of the lazy way to do it.

I think it is possible to expose the time during the callback/future completion during the network poll (because it is computed at the top of the background thread loop and pass down to network poll.

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.

Actually, could we use ClientResponse.receivedTimeMs?

}

private void handleException(final Throwable exception, final long responseTimeMs) {
if (exception instanceof TimeoutException || !(exception instanceof RetriableException)) {

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.

TimeoutException is a RetriableException. Should we just treat it as other RetriableException? That seems to be what the old consumer does.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just careful here because the current TopicMetadataFetcher handles 2 timeout cases differently regarding retries:

  • TimeoutException contained in a MetadataResponse as a response error is retried here
  • TimeoutException in getting the actual MetadataResponse throws exception here

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.

I think for now - the manager will continue to retry all RetriableException including TimeoutException. Currently, we don't have a way to cancel the request when the user API request times-out, so this is a gap there, but a jira is filed here: https://issues.apache.org/jira/browse/KAFKA-15475

private final LogContext logContext;

public TopicMetadataRequestManager(final LogContext logContext, final ConsumerConfig config) {
this.logContext = logContext;

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.

Could we just get rid of this? Ditto below.

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.

sorry - got into the habit of using this. 😅

final long retryBackoffMaxMs) {
super(logContext, TopicMetadataRequestState.class.getSimpleName(), retryBackoffMs,
retryBackoffMaxMs);
this.future = new CompletableFuture<>();

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.

Could we just get rid of this?

* {@link org.apache.kafka.clients.consumer.internals.NetworkClientDelegate.UnsentRequest} if needed.
*/
private Optional<NetworkClientDelegate.UnsentRequest> send(final long currentTimeMs) {
if (!this.canSendRequest(currentTimeMs)) {

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.

It would be useful to be consistent in convention. If we want to add this in front of methods in the parent class, we want to do this consistently.

future.complete(res);
inflightRequests.remove(topic);
} catch (RetriableException e) {
onFailedAttempt(responseTimeMs);

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.

The case that I am wondering is the following.

DefaultBackgroundThread is in a retry loop for an inflightRequest. PrototypeAsyncConsumer.partitionsFor eventually calls CompletableApplicationEvent.get(Timer timer) and times out. Do we still keep the request in inflightRequests at that point? Is that a concern?

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.

Thanks Jun for raising this point - I think what we should do is to complete the request with a non-retriable exception to prevent the request from retrying. Otherwise - the request manager will never remove the request from the inflightRequest.

private void retry(final long currentTimeMs) {
onFailedAttempt(currentTimeMs);
onSendAttempt(currentTimeMs);
this.onFailedAttempt(currentTimeMs);

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.

currentTimeMs is when the request is sent, not when the response is receive. Could we pass along ClientResponse.receivedTimeMs?

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.

Thanks for catching this.

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.

Addressed, see line #259


private void processResponseOrException(final ClientResponse response,
final Throwable exception) {
long responseTimeMs = System.currentTimeMillis();

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.

Actually, could we use ClientResponse.receivedTimeMs?

@philipnee
philipnee force-pushed the cherry-pick-topic-metadata branch from 920d63b to ec600b3 Compare September 18, 2023 04:09
* Whether there is an existing coordinator.
* Whether there is an inflight request.
* Whether the backoff timer has expired.
* The {@link org.apache.kafka.clients.consumer.internals.NetworkClientDelegate.PollResult} contains either a wait timer

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.

just cleaning up long references

@philipnee

philipnee commented Sep 19, 2023

Copy link
Copy Markdown
Contributor Author

@junrao @lianetm - I hope I've addressed most, if not all, comments that you pointed out. So, thank you both for spending time reviewing my code.

We did have an offline discussion about user API timeout handling, and a bug report is filed here KAFKA-15475. I will submit a patch after this PR to address this small gap.

Lastly, here are the failing tests:

Build / JDK 20 and Scala 2.13 / testReplication() – org.apache.kafka.connect.mirror.integration.MirrorConnectorsIntegrationExactlyOnceTest
53s
Build / JDK 17 and Scala 2.13 / testMultiWorkerRestartOnlyConnector – org.apache.kafka.connect.integration.ConnectorRestartApiIntegrationTest
2m 24s
Build / JDK 17 and Scala 2.13 / testCreateTokenForOtherUserFails(String).quorum=kraft – kafka.api.DelegationTokenEndToEndAuthorizationWithOwnerTest
9s
Build / JDK 11 and Scala 2.13 / testConfigurationOperations() – org.apache.kafka.controller.QuorumControllerTest
<1s
Build / JDK 11 and Scala 2.13 / executeTieredStorageTest(String).quorum=zk – org.apache.kafka.tiered.storage.integration.EnableRemoteLogOnTopicTest
43s
Build / JDK 8 and Scala 2.12 / testMultiWorkerRestartOnlyConnector – org.apache.kafka.connect.integration.ConnectorRestartApiIntegrationTest
2m 25s

I believe these are flaky.

@junrao junrao left a comment

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.

@philipnee : Thanks for the updated PR. Just a few minor comments.


public TopicMetadataRequestManager(final LogContext context, final ConsumerConfig config) {
logContext = context;
log = logContext.logger(this.getClass());

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.

Could we remove this?

}

private void completeFutureAndRemoveRequest(final Throwable throwable) {
this.future.completeExceptionally(throwable);

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.

Could we remove this?


/**
* Poll for the {@link OffsetFetchRequest} and {@link OffsetCommitRequest} request if there's any. The function will
* Poll for the {@link OffsetFetchRequest} and {@link OffsetCommitRequestState} request if there's any. The function will

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.

Hmm, OffsetCommitRequestState should be OffsetCommitRequest, right?

List<OffsetFetchRequestState> inflightOffsetFetches = new ArrayList<>();

public boolean hasUnsentRequests() {
// Visible for teseting

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.

typo teseting

* <p>If the request is new, it invokes a callback to remove itself from the {@code inflightOffsetFetches}
* upon completion.</>
* <p>If the request is new, it invokes a callback to remove itself from the {@code inflightOffsetFetches}
* upon completion.</>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: wrong tag </> and other unclosed ones above

* Clear {@code unsentOffsetCommits} and moves all the sendable request in {@code unsentOffsetFetches} to the
* {@code inflightOffsetFetches} to bookkeep all of the inflight requests.
*
* <p>

@lianetm lianetm Sep 19, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

was the intention here to add an extra line in-between? should be <p/> if so

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.

😓 - must be the residual from some edits..

Updates based on review comments
@philipnee

Copy link
Copy Markdown
Contributor Author

@junrao @lianetm - Thanks for another round of reviews. The latest build passed with the following test failures

Build / JDK 17 and Scala 2.13 / testBecomeFollowerWhileOldClientFetchInPurgatory() – kafka.server.ReplicaManagerTest
<1s
Build / JDK 17 and Scala 2.13 / [1] enableRemoteStorage=true – kafka.server.ReplicaManagerTest
<1s
Build / JDK 20 and Scala 2.13 / testRackAwareRangeAssignor() – integration.kafka.server.FetchFromFollowerIntegrationTest
46s
Build / JDK 20 and Scala 2.13 / testBumpTransactionalEpoch(String).quorum=zk – kafka.api.TransactionsTest
13s
Build / JDK 20 and Scala 2.13 / testCommitTransactionTimeout(String).quorum=kraft – kafka.api.TransactionsTest
9s
Build / JDK 20 and Scala 2.13 / executeTieredStorageTest(String).quorum=kraft – org.apache.kafka.tiered.storage.integration.DeleteTopicTest
41s
Build / JDK 11 and Scala 2.13 / testCloseDuringRebalance() – kafka.api.ConsumerBounceTest
10s
Build / JDK 11 and Scala 2.13 / [2] Type=Raft-Isolated, Name=testDescribeQuorumReplicationSuccessful, MetadataVersion=3.7-IV0, Security=PLAINTEXT – org.apache.kafka.tools.MetadataQuorumCommandTest
1m 8s
Build / JDK 8 and Scala 2.12 / testMultiWorkerRestartOnlyConnector – org.apache.kafka.connect.integration.ConnectorRestartApiIntegrationTest
2m 31s
Build / JDK 8 and Scala 2.12 / testBalancePartitionLeaders() – org.apache.kafka.controller.QuorumControllerTest

I believe they are irrelevant.

@junrao junrao left a comment

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.

@philipnee : Thanks for the latest PR. LGTM

@junrao
junrao merged commit 7d89bdc into apache:trunk Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ctr Consumer Threading Refactor (KIP-848)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants