This is an automated email from the ASF dual-hosted git repository.

danny0405 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/master by this push:
     new 9086d9819a5d fix(kafka-connect): retry start commit when the topic 
partition lookup fails (#20312)
9086d9819a5d is described below

commit 9086d9819a5d15ac4b0cf40d6a7bd39e58e0b894
Author: Vova Kolmakov <[email protected]>
AuthorDate: Thu Oct 15 10:04:45 2026 +0700

    fix(kafka-connect): retry start commit when the topic partition lookup 
fails (#20312)
    
    Co-authored-by: Vova Kolmakov <[email protected]>
---
 .../transaction/ConnectTransactionCoordinator.java |  2 +-
 .../connect/TestConnectTransactionCoordinator.java | 42 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git 
a/hudi-kafka-connect/src/main/java/org/apache/hudi/connect/transaction/ConnectTransactionCoordinator.java
 
b/hudi-kafka-connect/src/main/java/org/apache/hudi/connect/transaction/ConnectTransactionCoordinator.java
index 7ab4bb3a040c..55bc71a98ad3 100644
--- 
a/hudi-kafka-connect/src/main/java/org/apache/hudi/connect/transaction/ConnectTransactionCoordinator.java
+++ 
b/hudi-kafka-connect/src/main/java/org/apache/hudi/connect/transaction/ConnectTransactionCoordinator.java
@@ -302,9 +302,9 @@ public class ConnectTransactionCoordinator implements 
TransactionCoordinator, Ru
   }
 
   private void startNewCommit() {
-    numPartitions = 
partitionProvider.getLatestNumPartitions(configs.getString(BOOTSTRAP_SERVERS_CFG),
 partition.topic());
     partitionsWriteStatusReceived.clear();
     try {
+      numPartitions = 
partitionProvider.getLatestNumPartitions(configs.getString(BOOTSTRAP_SERVERS_CFG),
 partition.topic());
       currentCommitTime = transactionServices.startCommit();
       
kafkaControlClient.publishMessage(buildControlMessage(ControlMessage.EventType.START_COMMIT));
       currentState = State.STARTED_COMMIT;
diff --git 
a/hudi-kafka-connect/src/test/java/org/apache/hudi/connect/TestConnectTransactionCoordinator.java
 
b/hudi-kafka-connect/src/test/java/org/apache/hudi/connect/TestConnectTransactionCoordinator.java
index 5ce1710bb785..8d5128a3d2f3 100644
--- 
a/hudi-kafka-connect/src/test/java/org/apache/hudi/connect/TestConnectTransactionCoordinator.java
+++ 
b/hudi-kafka-connect/src/test/java/org/apache/hudi/connect/TestConnectTransactionCoordinator.java
@@ -21,6 +21,7 @@ package org.apache.hudi.connect;
 import org.apache.hudi.client.WriteStatus;
 import org.apache.hudi.common.model.HoodieRecord;
 import org.apache.hudi.common.util.Option;
+import org.apache.hudi.connect.kafka.KafkaControlAgent;
 import org.apache.hudi.connect.transaction.ConnectTransactionCoordinator;
 import org.apache.hudi.connect.transaction.TransactionCoordinator;
 import org.apache.hudi.connect.transaction.TransactionParticipant;
@@ -34,6 +35,7 @@ import lombok.Getter;
 import org.apache.kafka.common.TopicPartition;
 import org.apache.kafka.connect.sink.SinkRecord;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
 
@@ -44,9 +46,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
 
 public class TestConnectTransactionCoordinator {
 
@@ -101,6 +107,42 @@ public class TestConnectTransactionCoordinator {
     participant.stop();
   }
 
+  @Test
+  public void testRetryStartCommitWhenPartitionLookupFails() {
+    KafkaControlAgent controlAgent = mock(KafkaControlAgent.class);
+    AtomicInteger partitionLookups = new AtomicInteger();
+    // The first lookup fails, e.g. because the Kafka brokers are briefly 
unreachable
+    ConnectTransactionCoordinator.KafkaPartitionProvider partitionProvider = 
(bootstrapServers, topicName) -> {
+      if (partitionLookups.getAndIncrement() == 0) {
+        throw new HoodieException("Failed to fetch the latest number of 
partitions");
+      }
+      return TOTAL_KAFKA_PARTITIONS;
+    };
+    configs = KafkaConnectConfigs.newBuilder()
+        .withCommitIntervalSecs(60L)
+        .withCoordinatorWriteTimeoutSecs(60L)
+        .build();
+
+    TransactionCoordinator coordinator = new ConnectTransactionCoordinator(
+        configs,
+        new TopicPartition(TOPIC_NAME, 0),
+        controlAgent,
+        transactionServices,
+        partitionProvider);
+    try {
+      coordinator.start();
+
+      // The coordinator retries instead of stalling, and the failed attempt 
started no instant,
+      // so the commit that starts is the first one handed out by 
MockConnectTransactionServices
+      verify(controlAgent, timeout(TimeUnit.SECONDS.toMillis(10)))
+          .publishMessage(argThat(message -> message.getType() == 
ControlMessage.EventType.START_COMMIT
+              && message.getCommitTime().equals("101")));
+      assertEquals(2, partitionLookups.get());
+    } finally {
+      coordinator.stop();
+    }
+  }
+
   /**
    * A mock Transaction Participant, that exercises all the test scenarios
    * for the coordinator as mentioned in {@link TestScenarios}.

Reply via email to