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

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


The following commit(s) were added to refs/heads/release-1.16 by this push:
     new a9592c075d3 [FLINK-22243] Reactive Mode parallelism changes are not 
shown in the job graph visualization in the UI
a9592c075d3 is described below

commit a9592c075d3130e1d6af3748f201de3e973c3d0e
Author: Dawid Wysakowicz <[email protected]>
AuthorDate: Fri Sep 30 11:14:19 2022 +0200

    [FLINK-22243] Reactive Mode parallelism changes are not shown in the job 
graph visualization in the UI
    
    Update the JsonPlan of ExecutionGraph with the correct parallelism instead 
of using the original one from the JobGraph.
---
 .../jobgraph/jsonplan/JsonPlanGenerator.java       | 50 ++++++++++++++++---
 .../scheduler/adaptive/CreatingExecutionGraph.java | 19 ++++++++
 .../adaptive/StateTrackingMockExecutionGraph.java  |  8 ++-
 .../flink/test/scheduling/ReactiveModeITCase.java  | 57 ++++++++++++++++++++++
 4 files changed, 123 insertions(+), 11 deletions(-)

diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
index 63e95ea81f6..30414506435 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
@@ -18,9 +18,14 @@
 
 package org.apache.flink.runtime.jobgraph.jsonplan;
 
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.api.common.JobID;
 import org.apache.flink.runtime.jobgraph.JobEdge;
 import org.apache.flink.runtime.jobgraph.JobGraph;
+import org.apache.flink.runtime.jobgraph.JobType;
 import org.apache.flink.runtime.jobgraph.JobVertex;
+import org.apache.flink.runtime.jobgraph.JobVertexID;
+import org.apache.flink.runtime.scheduler.adaptive.allocator.VertexParallelism;
 
 import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonFactory;
 import 
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonGenerator;
@@ -28,14 +33,43 @@ import 
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonGenerator
 import org.apache.commons.lang3.StringEscapeUtils;
 
 import java.io.StringWriter;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
+@Internal
 public class JsonPlanGenerator {
 
     private static final String NOT_SET = "";
     private static final String EMPTY = "{}";
+    private static final VertexParallelism EMPTY_VERTEX_PARALLELISM =
+            new VertexParallelism() {
+                @Override
+                public Map<JobVertexID, Integer> 
getMaxParallelismForVertices() {
+                    return Collections.emptyMap();
+                }
+
+                @Override
+                public int getParallelism(JobVertexID jobVertexId) {
+                    return -1;
+                }
+            };
 
     public static String generatePlan(JobGraph jg) {
+        return generatePlan(
+                jg.getJobID(),
+                jg.getName(),
+                jg.getJobType(),
+                jg.getVertices(),
+                EMPTY_VERTEX_PARALLELISM);
+    }
+
+    public static String generatePlan(
+            JobID jobID,
+            String jobName,
+            JobType jobType,
+            Iterable<JobVertex> vertices,
+            VertexParallelism vertexParallelism) {
         try {
             final StringWriter writer = new StringWriter(1024);
 
@@ -44,13 +78,13 @@ public class JsonPlanGenerator {
 
             // start of everything
             gen.writeStartObject();
-            gen.writeStringField("jid", jg.getJobID().toString());
-            gen.writeStringField("name", jg.getName());
-            gen.writeStringField("type", jg.getJobType().name());
+            gen.writeStringField("jid", jobID.toString());
+            gen.writeStringField("name", jobName);
+            gen.writeStringField("type", jobType.name());
             gen.writeArrayFieldStart("nodes");
 
             // info per vertex
-            for (JobVertex vertex : jg.getVertices()) {
+            for (JobVertex vertex : vertices) {
 
                 String operator =
                         vertex.getOperatorName() != null ? 
vertex.getOperatorName() : NOT_SET;
@@ -81,8 +115,12 @@ public class JsonPlanGenerator {
                 gen.writeStartObject();
 
                 // write the core properties
-                gen.writeStringField("id", vertex.getID().toString());
-                gen.writeNumberField("parallelism", vertex.getParallelism());
+                JobVertexID vertexID = vertex.getID();
+                int storeParallelism = 
vertexParallelism.getParallelism(vertexID);
+                gen.writeStringField("id", vertexID.toString());
+                gen.writeNumberField(
+                        "parallelism",
+                        storeParallelism != -1 ? storeParallelism : 
vertex.getParallelism());
                 gen.writeStringField("operator", operator);
                 gen.writeStringField("operator_strategy", operatorDescr);
                 gen.writeStringField("description", description);
diff --git 
a/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
 
b/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
index a4db25a552c..08ce28e3b51 100644
--- 
a/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
+++ 
b/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
@@ -24,6 +24,8 @@ import org.apache.flink.runtime.execution.ExecutionState;
 import org.apache.flink.runtime.executiongraph.ArchivedExecutionGraph;
 import org.apache.flink.runtime.executiongraph.ExecutionGraph;
 import org.apache.flink.runtime.executiongraph.ExecutionVertex;
+import org.apache.flink.runtime.jobgraph.JobType;
+import org.apache.flink.runtime.jobgraph.jsonplan.JsonPlanGenerator;
 import org.apache.flink.runtime.scheduler.DefaultOperatorCoordinatorHandler;
 import org.apache.flink.runtime.scheduler.ExecutionGraphHandler;
 import org.apache.flink.runtime.scheduler.GlobalFailureHandler;
@@ -41,6 +43,7 @@ import java.util.Collections;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledFuture;
+import java.util.stream.StreamSupport;
 
 /**
  * State which waits for the creation of the {@link ExecutionGraph}. If the 
creation fails, then the
@@ -115,6 +118,22 @@ public class CreatingExecutionGraph implements State {
                 operatorCoordinatorHandler.initializeOperatorCoordinators(
                         context.getMainThreadExecutor());
                 operatorCoordinatorHandler.startAllOperatorCoordinators();
+                String updatedPlan =
+                        JsonPlanGenerator.generatePlan(
+                                executionGraph.getJobID(),
+                                executionGraph.getJobName(),
+                                JobType.STREAMING, // Adaptive scheduler works 
only with STREAMING
+                                // jobs
+                                () ->
+                                        StreamSupport.stream(
+                                                        executionGraph
+                                                                
.getAllExecutionVertices()
+                                                                .spliterator(),
+                                                        false)
+                                                .map(v -> 
v.getJobVertex().getJobVertex())
+                                                .iterator(),
+                                
executionGraphWithVertexParallelism.getVertexParallelism());
+                executionGraph.setJsonPlan(updatedPlan);
                 context.goToExecuting(
                         result.getExecutionGraph(),
                         executionGraphHandler,
diff --git 
a/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
 
b/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
index 9f3c9ba321a..54a65ccddcd 100644
--- 
a/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
+++ 
b/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
@@ -172,6 +172,9 @@ class StateTrackingMockExecutionGraph implements 
ExecutionGraph {
         return "";
     }
 
+    @Override
+    public void setJsonPlan(String jsonPlan) {}
+
     @Override
     public JobID getJobID() {
         return jobId;
@@ -285,11 +288,6 @@ class StateTrackingMockExecutionGraph implements 
ExecutionGraph {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public void setJsonPlan(String jsonPlan) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public Configuration getJobConfiguration() {
         throw new UnsupportedOperationException();
diff --git 
a/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
 
b/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
index 5939dbd9b94..d8dd6a86bab 100644
--- 
a/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
+++ 
b/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
@@ -25,6 +25,7 @@ import org.apache.flink.configuration.Configuration;
 import org.apache.flink.configuration.JobManagerOptions;
 import org.apache.flink.configuration.SchedulerExecutionMode;
 import org.apache.flink.core.execution.JobClient;
+import org.apache.flink.runtime.executiongraph.ArchivedExecutionGraph;
 import org.apache.flink.runtime.rest.messages.job.JobDetailsInfo;
 import org.apache.flink.runtime.testutils.CommonTestUtils;
 import org.apache.flink.runtime.testutils.MiniClusterResourceConfiguration;
@@ -35,6 +36,9 @@ import 
org.apache.flink.streaming.api.functions.source.RichParallelSourceFunctio
 import org.apache.flink.streaming.api.functions.source.SourceFunction;
 import org.apache.flink.test.util.MiniClusterWithClientResource;
 import org.apache.flink.util.TestLogger;
+import org.apache.flink.util.jackson.JacksonMapperFactory;
+
+import 
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -42,6 +46,8 @@ import org.junit.rules.TemporaryFolder;
 
 import java.util.concurrent.ExecutionException;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 /** Tests for Reactive Mode (FLIP-159). */
 public class ReactiveModeITCase extends TestLogger {
     private static final int NUMBER_SLOTS_PER_TASK_MANAGER = 2;
@@ -49,6 +55,8 @@ public class ReactiveModeITCase extends TestLogger {
 
     private static final Configuration configuration = 
getReactiveModeConfiguration();
 
+    private static final ObjectMapper OBJECT_MAPPER = 
JacksonMapperFactory.createObjectMapper();
+
     @Rule public TemporaryFolder tempFolder = new TemporaryFolder();
 
     @Rule
@@ -110,6 +118,55 @@ public class ReactiveModeITCase extends TestLogger {
                 NUMBER_SLOTS_PER_TASK_MANAGER * (INITIAL_NUMBER_TASK_MANAGERS 
+ 1));
     }
 
+    @Test
+    public void testJsonPlanParallelismAfterRescale() throws Exception {
+        StreamExecutionEnvironment env = 
StreamExecutionEnvironment.getExecutionEnvironment();
+        final DataStream<String> input = env.addSource(new DummySource());
+        input.addSink(new DiscardingSink<>());
+
+        final JobClient jobClient = env.executeAsync();
+
+        int initialParallelism = NUMBER_SLOTS_PER_TASK_MANAGER * 
INITIAL_NUMBER_TASK_MANAGERS;
+        waitUntilParallelismForVertexReached(
+                miniClusterResource.getRestClusterClient(),
+                jobClient.getJobID(),
+                initialParallelism);
+
+        ArchivedExecutionGraph archivedExecutionGraph =
+                miniClusterResource
+                        .getMiniCluster()
+                        .getArchivedExecutionGraph(jobClient.getJobID())
+                        .get();
+
+        assertThat(
+                        OBJECT_MAPPER
+                                .readTree(archivedExecutionGraph.getJsonPlan())
+                                .findValues("parallelism"))
+                .allMatch(n -> n.asInt() == initialParallelism);
+
+        // scale up to 2 TaskManagers:
+        miniClusterResource.getMiniCluster().startTaskManager();
+
+        int rescaledParallelism =
+                NUMBER_SLOTS_PER_TASK_MANAGER * (INITIAL_NUMBER_TASK_MANAGERS 
+ 1);
+        waitUntilParallelismForVertexReached(
+                miniClusterResource.getRestClusterClient(),
+                jobClient.getJobID(),
+                rescaledParallelism);
+
+        archivedExecutionGraph =
+                miniClusterResource
+                        .getMiniCluster()
+                        .getArchivedExecutionGraph(jobClient.getJobID())
+                        .get();
+
+        assertThat(
+                        OBJECT_MAPPER
+                                .readTree(archivedExecutionGraph.getJsonPlan())
+                                .findValues("parallelism"))
+                .allMatch(n -> n.asInt() == rescaledParallelism);
+    }
+
     @Test
     public void testScaleDownOnTaskManagerLoss() throws Exception {
         // test preparation: ensure we have 2 TaskManagers running

Reply via email to