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

lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new 906b918ea [flink] Resolve bounded stream input finished in multiple 
checkpoint interval then cause commit failed (#2462)
906b918ea is described below

commit 906b918ea2d8fd92a50c10fd66c01a9fa6a6bbf5
Author: YeJunHao <[email protected]>
AuthorDate: Wed Dec 13 18:02:03 2023 +0800

    [flink] Resolve bounded stream input finished in multiple checkpoint 
interval then cause commit failed (#2462)
---
 .../org/apache/paimon/flink/sink/Committer.java    |   3 +
 .../paimon/flink/sink/CommitterOperator.java       |  21 +++-
 .../apache/paimon/flink/sink/StoreCommitter.java   |   9 ++
 .../paimon/flink/sink/StoreMultiCommitter.java     |  10 +-
 .../paimon/flink/sink/CommitterOperatorTest.java   | 135 +++++++++++++++++++++
 5 files changed, 174 insertions(+), 4 deletions(-)

diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/Committer.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/Committer.java
index a58d97e4c..328c95e40 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/Committer.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/Committer.java
@@ -41,6 +41,9 @@ public interface Committer<CommitT, GlobalCommitT> extends 
AutoCloseable {
     GlobalCommitT combine(long checkpointId, long watermark, List<CommitT> 
committables)
             throws IOException;
 
+    GlobalCommitT combine(
+            long checkpointId, long watermark, GlobalCommitT t, List<CommitT> 
committables);
+
     /** Commits the given {@link GlobalCommitT}. */
     void commit(List<GlobalCommitT> globalCommittables) throws IOException, 
InterruptedException;
 
diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/CommitterOperator.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/CommitterOperator.java
index 16563cb77..4d8b3a4f5 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/CommitterOperator.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/CommitterOperator.java
@@ -193,16 +193,31 @@ public class CommitterOperator<CommitT, GlobalCommitT> 
extends AbstractStreamOpe
         for (Map.Entry<Long, List<CommitT>> entry : grouped.entrySet()) {
             Long cp = entry.getKey();
             List<CommitT> committables = entry.getValue();
-            if (committablesPerCheckpoint.containsKey(cp)) {
+            // To prevent the asynchronous completion of tasks with multiple 
concurrent bounded
+            // stream inputs, which leads to some tasks passing a Committable 
with cp =
+            // Long.MAX_VALUE during the endInput method call of the current 
checkpoint, while other
+            // tasks pass a Committable with Long.MAX_VALUE during other 
checkpoints hence causing
+            // an error here, we have a special handling for Committables with 
Long.MAX_VALUE:
+            // instead of throwing an error, we merge them.
+            if (cp != null && cp == Long.MAX_VALUE && 
committablesPerCheckpoint.containsKey(cp)) {
+                // Merge the Long.MAX_VALUE committables here.
+                GlobalCommitT commitT =
+                        committer.combine(
+                                cp,
+                                currentWatermark,
+                                committablesPerCheckpoint.get(cp),
+                                committables);
+                committablesPerCheckpoint.put(cp, commitT);
+            } else if (committablesPerCheckpoint.containsKey(cp)) {
                 throw new RuntimeException(
                         String.format(
                                 "Repeatedly commit the same checkpoint files. 
\n"
                                         + "The previous files is %s, \n"
                                         + "and the subsequent files is %s",
                                 committablesPerCheckpoint.get(cp), 
committables));
+            } else {
+                committablesPerCheckpoint.put(cp, toCommittables(cp, 
committables));
             }
-
-            committablesPerCheckpoint.put(cp, toCommittables(cp, 
committables));
         }
 
         this.inputs.clear();
diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreCommitter.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreCommitter.java
index 7857242bd..620bcbbc4 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreCommitter.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreCommitter.java
@@ -69,6 +69,15 @@ public class StoreCommitter implements 
Committer<Committable, ManifestCommittabl
     public ManifestCommittable combine(
             long checkpointId, long watermark, List<Committable> committables) 
{
         ManifestCommittable manifestCommittable = new 
ManifestCommittable(checkpointId, watermark);
+        return combine(checkpointId, watermark, manifestCommittable, 
committables);
+    }
+
+    @Override
+    public ManifestCommittable combine(
+            long checkpointId,
+            long watermark,
+            ManifestCommittable manifestCommittable,
+            List<Committable> committables) {
         for (Committable committable : committables) {
             switch (committable.kind()) {
                 case FILE:
diff --git 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreMultiCommitter.java
 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreMultiCommitter.java
index 089311208..a2d3f16ba 100644
--- 
a/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreMultiCommitter.java
+++ 
b/paimon-flink/paimon-flink-common/src/main/java/org/apache/paimon/flink/sink/StoreMultiCommitter.java
@@ -89,8 +89,16 @@ public class StoreMultiCommitter
             long checkpointId, long watermark, List<MultiTableCommittable> 
committables) {
         WrappedManifestCommittable wrappedManifestCommittable =
                 new WrappedManifestCommittable(checkpointId, watermark);
-        for (MultiTableCommittable committable : committables) {
+        return combine(checkpointId, watermark, wrappedManifestCommittable, 
committables);
+    }
 
+    @Override
+    public WrappedManifestCommittable combine(
+            long checkpointId,
+            long watermark,
+            WrappedManifestCommittable wrappedManifestCommittable,
+            List<MultiTableCommittable> committables) {
+        for (MultiTableCommittable committable : committables) {
             ManifestCommittable manifestCommittable =
                     wrappedManifestCommittable.computeCommittableIfAbsent(
                             Identifier.create(committable.getDatabase(), 
committable.getTable()),
diff --git 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/sink/CommitterOperatorTest.java
 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/sink/CommitterOperatorTest.java
index a30be40ef..6c4b46ce3 100644
--- 
a/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/sink/CommitterOperatorTest.java
+++ 
b/paimon-flink/paimon-flink-common/src/test/java/org/apache/paimon/flink/sink/CommitterOperatorTest.java
@@ -25,10 +25,13 @@ import org.apache.paimon.data.GenericRow;
 import org.apache.paimon.flink.VersionedSerializerWrapper;
 import org.apache.paimon.flink.utils.MetricUtils;
 import org.apache.paimon.fs.local.LocalFileIO;
+import org.apache.paimon.io.CompactIncrement;
+import org.apache.paimon.io.NewFilesIncrement;
 import org.apache.paimon.manifest.ManifestCommittable;
 import org.apache.paimon.manifest.ManifestCommittableSerializer;
 import org.apache.paimon.table.FileStoreTable;
 import org.apache.paimon.table.sink.CommitMessage;
+import org.apache.paimon.table.sink.CommitMessageImpl;
 import org.apache.paimon.table.sink.StreamTableCommit;
 import org.apache.paimon.table.sink.StreamTableWrite;
 import org.apache.paimon.table.sink.StreamWriteBuilder;
@@ -278,6 +281,138 @@ public class CommitterOperatorTest extends 
CommitterOperatorTestBase {
         
Assertions.assertThat(actual).hasSameElementsAs(Lists.newArrayList(commitUser));
     }
 
+    @Test
+    public void testCommitInputEnd() throws Exception {
+        FileStoreTable table = createFileStoreTable();
+        String commitUser = UUID.randomUUID().toString();
+        OneInputStreamOperator<Committable, Committable> operator =
+                createCommitterOperator(table, commitUser, new 
NoopCommittableStateManager());
+        OneInputStreamOperatorTestHarness<Committable, Committable> 
testHarness =
+                createTestHarness(operator);
+        testHarness.open();
+        Assertions.assertThatCode(
+                        () -> {
+                            long time = System.currentTimeMillis();
+                            long cp = 0L;
+                            testHarness.processElement(
+                                    new Committable(
+                                            Long.MAX_VALUE,
+                                            Committable.Kind.FILE,
+                                            new CommitMessageImpl(
+                                                    BinaryRow.EMPTY_ROW,
+                                                    0,
+                                                    new NewFilesIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()),
+                                                    new CompactIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()))),
+                                    cp);
+                            testHarness.snapshot(cp++, time++);
+                            testHarness.processElement(
+                                    new Committable(
+                                            Long.MAX_VALUE,
+                                            Committable.Kind.FILE,
+                                            new CommitMessageImpl(
+                                                    BinaryRow.EMPTY_ROW,
+                                                    0,
+                                                    new NewFilesIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()),
+                                                    new CompactIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()))),
+                                    cp);
+                            testHarness.processElement(
+                                    new Committable(
+                                            Long.MAX_VALUE,
+                                            Committable.Kind.FILE,
+                                            new CommitMessageImpl(
+                                                    BinaryRow.EMPTY_ROW,
+                                                    0,
+                                                    new NewFilesIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()),
+                                                    new CompactIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()))),
+                                    cp);
+                            testHarness.snapshot(cp++, time++);
+                            testHarness.snapshot(cp, time);
+                        })
+                .doesNotThrowAnyException();
+
+        if (operator instanceof CommitterOperator) {
+            Assertions.assertThat(
+                            ((ManifestCommittable)
+                                            ((CommitterOperator) operator)
+                                                    
.committablesPerCheckpoint.get(Long.MAX_VALUE))
+                                    .fileCommittables()
+                                    .size())
+                    .isEqualTo(3);
+        }
+
+        Assertions.assertThatCode(
+                        () -> {
+                            long time = System.currentTimeMillis();
+                            long cp = 0L;
+                            testHarness.processElement(
+                                    new Committable(
+                                            0L,
+                                            Committable.Kind.FILE,
+                                            new CommitMessageImpl(
+                                                    BinaryRow.EMPTY_ROW,
+                                                    0,
+                                                    new NewFilesIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()),
+                                                    new CompactIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()))),
+                                    cp);
+                            testHarness.snapshot(cp++, time++);
+                            testHarness.processElement(
+                                    new Committable(
+                                            0L,
+                                            Committable.Kind.FILE,
+                                            new CommitMessageImpl(
+                                                    BinaryRow.EMPTY_ROW,
+                                                    0,
+                                                    new NewFilesIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()),
+                                                    new CompactIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()))),
+                                    cp);
+                            testHarness.processElement(
+                                    new Committable(
+                                            Long.MAX_VALUE,
+                                            Committable.Kind.FILE,
+                                            new CommitMessageImpl(
+                                                    BinaryRow.EMPTY_ROW,
+                                                    0,
+                                                    new NewFilesIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()),
+                                                    new CompactIncrement(
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList(),
+                                                            
Collections.emptyList()))),
+                                    cp);
+                            testHarness.snapshot(cp++, time++);
+                            testHarness.snapshot(cp, time);
+                        })
+                .hasRootCauseInstanceOf(RuntimeException.class)
+                .cause()
+                .hasMessageContaining("Repeatedly commit the same checkpoint 
files.");
+    }
+
     private static OperatorSubtaskState writeAndSnapshot(
             FileStoreTable table,
             String commitUser,

Reply via email to