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

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


The following commit(s) were added to refs/heads/master by this push:
     new cadfab59a9a [FLINK-29500] InitializeOnMaster uses wrong parallelism 
with AdaptiveScheduler
cadfab59a9a is described below

commit cadfab59a9a5f6eaaaae7f95e2a9fb3ad7b1b1d9
Author: Dawid Wysakowicz <[email protected]>
AuthorDate: Tue Oct 4 13:50:28 2022 +0200

    [FLINK-29500] InitializeOnMaster uses wrong parallelism with 
AdaptiveScheduler
    
    We change the signature of JobVertex#initializeOnMaster/finalizeOnMaster to 
pass a Context object. In this context we can pass
    the actual parallelism the vertex will be run with.
---
 .../executiongraph/DefaultExecutionGraph.java      |  5 +-
 .../DefaultExecutionGraphBuilder.java              |  7 +-
 .../SimpleInitializeOnMasterContext.java           | 45 ++++++++++++
 .../runtime/jobgraph/InputOutputFormatVertex.java  | 12 ++--
 .../apache/flink/runtime/jobgraph/JobVertex.java   | 21 ++++--
 .../flink/runtime/dispatcher/DispatcherTest.java   |  4 +-
 .../executiongraph/FinalizeOnMasterTest.java       |  6 +-
 .../flink/runtime/jobgraph/JobTaskVertexTest.java  | 79 ++++++++++++++++++++--
 .../runtime/minicluster/MiniClusterITCase.java     |  6 +-
 .../example/failing/JobSubmissionFailsITCase.java  |  2 +-
 10 files changed, 164 insertions(+), 23 deletions(-)

diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraph.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraph.java
index 164ff1eb567..3e4efea3758 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraph.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraph.java
@@ -1215,7 +1215,10 @@ public class DefaultExecutionGraph implements 
ExecutionGraph, InternalExecutionG
 
             try {
                 for (ExecutionJobVertex ejv : verticesInCreationOrder) {
-                    ejv.getJobVertex().finalizeOnMaster(getUserClassLoader());
+                    ejv.getJobVertex()
+                            .finalizeOnMaster(
+                                    new SimpleInitializeOnMasterContext(
+                                            getUserClassLoader(), 
ejv.getParallelism()));
                 }
             } catch (Throwable t) {
                 ExceptionUtils.rethrowIfFatalError(t);
diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraphBuilder.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraphBuilder.java
index 462664b2865..9dffbdf2619 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraphBuilder.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/DefaultExecutionGraphBuilder.java
@@ -173,7 +173,12 @@ public class DefaultExecutionGraphBuilder {
             }
 
             try {
-                vertex.initializeOnMaster(classLoader);
+                vertex.initializeOnMaster(
+                        new SimpleInitializeOnMasterContext(
+                                classLoader,
+                                vertexParallelismStore
+                                        .getParallelismInfo(vertex.getID())
+                                        .getParallelism()));
             } catch (Throwable t) {
                 throw new JobExecutionException(
                         jobId,
diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/SimpleInitializeOnMasterContext.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/SimpleInitializeOnMasterContext.java
new file mode 100644
index 00000000000..686300f7aca
--- /dev/null
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/executiongraph/SimpleInitializeOnMasterContext.java
@@ -0,0 +1,45 @@
+/*
+ * 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.flink.runtime.executiongraph;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.runtime.jobgraph.JobVertex;
+
+/** A simple pojo based implementation of {@link 
JobVertex.InitializeOnMasterContext}. */
+@Internal
+public final class SimpleInitializeOnMasterContext implements 
JobVertex.InitializeOnMasterContext {
+
+    private final ClassLoader loader;
+    private final int executionParallelism;
+
+    public SimpleInitializeOnMasterContext(ClassLoader loader, int 
executionParallelism) {
+        this.loader = loader;
+        this.executionParallelism = executionParallelism;
+    }
+
+    @Override
+    public ClassLoader getClassLoader() {
+        return loader;
+    }
+
+    @Override
+    public int getExecutionParallelism() {
+        return executionParallelism;
+    }
+}
diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/InputOutputFormatVertex.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/InputOutputFormatVertex.java
index 097ff181b45..9eb3e36cef7 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/InputOutputFormatVertex.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/InputOutputFormatVertex.java
@@ -53,7 +53,8 @@ public class InputOutputFormatVertex extends JobVertex {
     }
 
     @Override
-    public void initializeOnMaster(ClassLoader loader) throws Exception {
+    public void initializeOnMaster(InitializeOnMasterContext context) throws 
Exception {
+        ClassLoader loader = context.getClassLoader();
         final InputOutputFormatContainer formatContainer = 
initInputOutputformatContainer(loader);
 
         final ClassLoader original = 
Thread.currentThread().getContextClassLoader();
@@ -107,7 +108,8 @@ public class InputOutputFormatVertex extends JobVertex {
                 }
 
                 if (outputFormat instanceof InitializeOnMaster) {
-                    ((InitializeOnMaster) 
outputFormat).initializeGlobal(getParallelism());
+                    int executionParallelism = 
context.getExecutionParallelism();
+                    ((InitializeOnMaster) 
outputFormat).initializeGlobal(executionParallelism);
                 }
             }
         } finally {
@@ -117,7 +119,8 @@ public class InputOutputFormatVertex extends JobVertex {
     }
 
     @Override
-    public void finalizeOnMaster(ClassLoader loader) throws Exception {
+    public void finalizeOnMaster(InitializeOnMasterContext context) throws 
Exception {
+        final ClassLoader loader = context.getClassLoader();
         final InputOutputFormatContainer formatContainer = 
initInputOutputformatContainer(loader);
 
         final ClassLoader original = 
Thread.currentThread().getContextClassLoader();
@@ -145,7 +148,8 @@ public class InputOutputFormatVertex extends JobVertex {
                 }
 
                 if (outputFormat instanceof FinalizeOnMaster) {
-                    ((FinalizeOnMaster) 
outputFormat).finalizeGlobal(getParallelism());
+                    int executionParallelism = 
context.getExecutionParallelism();
+                    ((FinalizeOnMaster) 
outputFormat).finalizeGlobal(executionParallelism);
                 }
             }
         } finally {
diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobVertex.java 
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobVertex.java
index 717bd6d4376..3c7b42fe458 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobVertex.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/JobVertex.java
@@ -559,19 +559,32 @@ public class JobVertex implements java.io.Serializable {
      * A hook that can be overwritten by sub classes to implement logic that 
is called by the master
      * when the job starts.
      *
-     * @param loader The class loader for user defined code.
+     * @param context Provides contextual information for the initialization
      * @throws Exception The method may throw exceptions which cause the job 
to fail immediately.
      */
-    public void initializeOnMaster(ClassLoader loader) throws Exception {}
+    public void initializeOnMaster(InitializeOnMasterContext context) throws 
Exception {}
 
     /**
      * A hook that can be overwritten by sub classes to implement logic that 
is called by the master
      * after the job completed.
      *
-     * @param loader The class loader for user defined code.
+     * @param context Provides contextual information for the initialization
      * @throws Exception The method may throw exceptions which cause the job 
to fail immediately.
      */
-    public void finalizeOnMaster(ClassLoader loader) throws Exception {}
+    public void finalizeOnMaster(InitializeOnMasterContext context) throws 
Exception {}
+
+    public interface InitializeOnMasterContext {
+        /** The class loader for user defined code. */
+        ClassLoader getClassLoader();
+
+        /**
+         * The actual parallelism this vertex will be run with. In contrast, 
the {@link
+         * #getParallelism()} is the original parallelism set when creating 
the {@link JobGraph} and
+         * might be updated e.g. by the {@link
+         * org.apache.flink.runtime.scheduler.adaptive.AdaptiveScheduler}.
+         */
+        int getExecutionParallelism();
+    }
 
     // 
--------------------------------------------------------------------------------------------
 
diff --git 
a/flink-runtime/src/test/java/org/apache/flink/runtime/dispatcher/DispatcherTest.java
 
b/flink-runtime/src/test/java/org/apache/flink/runtime/dispatcher/DispatcherTest.java
index a51d8bfc8d8..0f8f130d5fb 100755
--- 
a/flink-runtime/src/test/java/org/apache/flink/runtime/dispatcher/DispatcherTest.java
+++ 
b/flink-runtime/src/test/java/org/apache/flink/runtime/dispatcher/DispatcherTest.java
@@ -1419,8 +1419,8 @@ public class DispatcherTest extends 
AbstractDispatcherTest {
         }
 
         @Override
-        public void initializeOnMaster(ClassLoader loader) throws Exception {
-            super.initializeOnMaster(loader);
+        public void initializeOnMaster(InitializeOnMasterContext context) 
throws Exception {
+            super.initializeOnMaster(context);
             oneShotLatch.await();
         }
 
diff --git 
a/flink-runtime/src/test/java/org/apache/flink/runtime/executiongraph/FinalizeOnMasterTest.java
 
b/flink-runtime/src/test/java/org/apache/flink/runtime/executiongraph/FinalizeOnMasterTest.java
index 3524cc14817..a302ce2e862 100644
--- 
a/flink-runtime/src/test/java/org/apache/flink/runtime/executiongraph/FinalizeOnMasterTest.java
+++ 
b/flink-runtime/src/test/java/org/apache/flink/runtime/executiongraph/FinalizeOnMasterTest.java
@@ -77,8 +77,8 @@ public class FinalizeOnMasterTest extends TestLogger {
         ExecutionGraphTestUtils.finishAllVertices(eg);
         assertEquals(JobStatus.FINISHED, eg.waitUntilTerminal());
 
-        verify(vertex1, times(1)).finalizeOnMaster(any(ClassLoader.class));
-        verify(vertex2, times(1)).finalizeOnMaster(any(ClassLoader.class));
+        verify(vertex1, 
times(1)).finalizeOnMaster(any(JobVertex.InitializeOnMasterContext.class));
+        verify(vertex2, 
times(1)).finalizeOnMaster(any(JobVertex.InitializeOnMasterContext.class));
 
         assertEquals(0, eg.getRegisteredExecutions().size());
     }
@@ -109,7 +109,7 @@ public class FinalizeOnMasterTest extends TestLogger {
 
         assertEquals(JobStatus.FAILED, eg.waitUntilTerminal());
 
-        verify(vertex, times(0)).finalizeOnMaster(any(ClassLoader.class));
+        verify(vertex, 
times(0)).finalizeOnMaster(any(JobVertex.InitializeOnMasterContext.class));
 
         assertEquals(0, eg.getRegisteredExecutions().size());
     }
diff --git 
a/flink-runtime/src/test/java/org/apache/flink/runtime/jobgraph/JobTaskVertexTest.java
 
b/flink-runtime/src/test/java/org/apache/flink/runtime/jobgraph/JobTaskVertexTest.java
index cf59753999f..d31fdb9d8bf 100644
--- 
a/flink-runtime/src/test/java/org/apache/flink/runtime/jobgraph/JobTaskVertexTest.java
+++ 
b/flink-runtime/src/test/java/org/apache/flink/runtime/jobgraph/JobTaskVertexTest.java
@@ -21,20 +21,26 @@ package org.apache.flink.runtime.jobgraph;
 import org.apache.flink.api.common.io.FinalizeOnMaster;
 import org.apache.flink.api.common.io.GenericInputFormat;
 import org.apache.flink.api.common.io.InitializeOnMaster;
+import org.apache.flink.api.common.io.OutputFormat;
 import org.apache.flink.api.java.io.DiscardingOutputFormat;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.core.io.GenericInputSplit;
 import org.apache.flink.core.io.InputSplit;
+import org.apache.flink.runtime.executiongraph.SimpleInitializeOnMasterContext;
 import org.apache.flink.runtime.io.network.partition.ResultPartitionType;
 import org.apache.flink.runtime.operators.util.TaskConfig;
+import org.apache.flink.testutils.junit.SharedObjectsExtension;
+import org.apache.flink.testutils.junit.SharedReference;
 import org.apache.flink.util.InstantiationUtil;
 
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -42,6 +48,8 @@ import static 
org.assertj.core.api.Assertions.assertThatThrownBy;
 @SuppressWarnings("serial")
 class JobTaskVertexTest {
 
+    @RegisterExtension final SharedObjectsExtension sharedObjects = 
SharedObjectsExtension.create();
+
     @Test
     void testMultipleConsumersVertices() {
         JobVertex producer = new JobVertex("producer");
@@ -117,17 +125,32 @@ class JobTaskVertexTest {
 
         final ClassLoader cl = new TestClassLoader();
 
-        assertThatThrownBy(() -> 
vertex.initializeOnMaster(cl)).isInstanceOf(TestException.class);
+        assertThatThrownBy(
+                        () ->
+                                vertex.initializeOnMaster(
+                                        new SimpleInitializeOnMasterContext(
+                                                cl, vertex.getParallelism())))
+                .isInstanceOf(TestException.class);
 
         InputOutputFormatVertex copy = InstantiationUtil.clone(vertex);
         ClassLoader ctxCl = Thread.currentThread().getContextClassLoader();
-        assertThatThrownBy(() -> 
copy.initializeOnMaster(cl)).isInstanceOf(TestException.class);
+        assertThatThrownBy(
+                        () ->
+                                copy.initializeOnMaster(
+                                        new SimpleInitializeOnMasterContext(
+                                                cl, copy.getParallelism())))
+                .isInstanceOf(TestException.class);
 
         assertThat(Thread.currentThread().getContextClassLoader())
                 .as("Previous classloader was not restored.")
                 .isEqualTo(ctxCl);
 
-        assertThatThrownBy(() -> 
copy.finalizeOnMaster(cl)).isInstanceOf(TestException.class);
+        assertThatThrownBy(
+                        () ->
+                                copy.finalizeOnMaster(
+                                        new SimpleInitializeOnMasterContext(
+                                                cl, copy.getParallelism())))
+                .isInstanceOf(TestException.class);
         assertThat(Thread.currentThread().getContextClassLoader())
                 .as("Previous classloader was not restored.")
                 .isEqualTo(ctxCl);
@@ -147,7 +170,7 @@ class JobTaskVertexTest {
 
         final ClassLoader cl = new TestClassLoader();
 
-        vertex.initializeOnMaster(cl);
+        vertex.initializeOnMaster(new SimpleInitializeOnMasterContext(cl, 
vertex.getParallelism()));
         InputSplit[] splits = 
vertex.getInputSplitSource().createInputSplits(77);
 
         assertThat(splits).isNotNull();
@@ -155,8 +178,56 @@ class JobTaskVertexTest {
         assertThat(splits[0].getClass()).isEqualTo(TestSplit.class);
     }
 
+    @Test
+    void testOutputFormatUsesCorrectParallelism() throws Exception {
+        final InputOutputFormatVertex vertex = new 
InputOutputFormatVertex("Name");
+        int initialParallelism = 1;
+        vertex.setParallelism(initialParallelism);
+
+        OperatorID operatorID = new OperatorID();
+        // just a mutable container for integer
+        SharedReference<AtomicInteger> globalParallelism = 
sharedObjects.add(new AtomicInteger());
+        new 
InputOutputFormatContainer(Thread.currentThread().getContextClassLoader())
+                .addOutputFormat(operatorID, new 
TestInitializeOutputFormat(globalParallelism))
+                .write(new TaskConfig(vertex.getConfiguration()));
+
+        int executionParallelism = initialParallelism + 3;
+        try (final TestClassLoader cl = new TestClassLoader()) {
+            vertex.initializeOnMaster(
+                    new SimpleInitializeOnMasterContext(cl, 
executionParallelism));
+            
assertThat(globalParallelism.get().get()).isEqualTo(executionParallelism);
+        }
+    }
+
     // 
--------------------------------------------------------------------------------------------
 
+    private static final class TestInitializeOutputFormat
+            implements OutputFormat<Object>, InitializeOnMaster {
+
+        private final SharedReference<AtomicInteger> globalParallelism;
+
+        private TestInitializeOutputFormat(SharedReference<AtomicInteger> 
globalParallelism) {
+            this.globalParallelism = globalParallelism;
+        }
+
+        @Override
+        public void configure(Configuration parameters) {}
+
+        @Override
+        public void open(int taskNumber, int numTasks) throws IOException {}
+
+        @Override
+        public void writeRecord(Object record) throws IOException {}
+
+        @Override
+        public void close() throws IOException {}
+
+        @Override
+        public void initializeGlobal(int parallelism) throws IOException {
+            globalParallelism.get().set(parallelism);
+        }
+    }
+
     private static final class TestException extends IOException {}
 
     private static final class TestSplit extends GenericInputSplit {
diff --git 
a/flink-runtime/src/test/java/org/apache/flink/runtime/minicluster/MiniClusterITCase.java
 
b/flink-runtime/src/test/java/org/apache/flink/runtime/minicluster/MiniClusterITCase.java
index 4efc67785f8..ccf600fea09 100644
--- 
a/flink-runtime/src/test/java/org/apache/flink/runtime/minicluster/MiniClusterITCase.java
+++ 
b/flink-runtime/src/test/java/org/apache/flink/runtime/minicluster/MiniClusterITCase.java
@@ -714,7 +714,7 @@ public class MiniClusterITCase extends TestLogger {
         }
 
         @Override
-        public void finalizeOnMaster(ClassLoader loader) throws Exception {
+        public void finalizeOnMaster(InitializeOnMasterContext context) throws 
Exception {
             Thread.sleep(waitingTime);
             finalizedOnMaster.set(true);
         }
@@ -731,7 +731,7 @@ public class MiniClusterITCase extends TestLogger {
         }
 
         @Override
-        public void finalizeOnMaster(ClassLoader loader) {
+        public void finalizeOnMaster(InitializeOnMasterContext context) {
             throw new OutOfMemoryError("Java heap space");
         }
     }
@@ -743,7 +743,7 @@ public class MiniClusterITCase extends TestLogger {
         }
 
         @Override
-        public void initializeOnMaster(ClassLoader loader) {
+        public void initializeOnMaster(InitializeOnMasterContext context) {
             throw new OutOfMemoryError("Java heap space");
         }
     }
diff --git 
a/flink-tests/src/test/java/org/apache/flink/test/example/failing/JobSubmissionFailsITCase.java
 
b/flink-tests/src/test/java/org/apache/flink/test/example/failing/JobSubmissionFailsITCase.java
index eb41e95a9b7..402ae192e60 100644
--- 
a/flink-tests/src/test/java/org/apache/flink/test/example/failing/JobSubmissionFailsITCase.java
+++ 
b/flink-tests/src/test/java/org/apache/flink/test/example/failing/JobSubmissionFailsITCase.java
@@ -147,7 +147,7 @@ public class JobSubmissionFailsITCase extends TestLogger {
         }
 
         @Override
-        public void initializeOnMaster(ClassLoader loader) throws Exception {
+        public void initializeOnMaster(InitializeOnMasterContext context) 
throws Exception {
             throw new Exception("Test exception.");
         }
     }

Reply via email to