You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by gu...@apache.org on 2023/02/27 14:47:24 UTC
[flink] 02/02: [FLINK-29816][streaming] Fix the bug that StreamTask doesn't handle exception during restoring
This is an automated email from the ASF dual-hosted git repository.
guoweijie pushed a commit to branch release-1.17
in repository https://gitbox.apache.org/repos/asf/flink.git
commit 65e455189d2a88fd62be2e8a464feab4687ee088
Author: Roc Marshal <fl...@126.com>
AuthorDate: Sun Feb 26 12:18:00 2023 +0800
[FLINK-29816][streaming] Fix the bug that StreamTask doesn't handle exception during restoring
(cherry picked from commit a98bb9a6c978d5458cf4cc11dc7b68034f4def4b)
---
.../flink/streaming/runtime/tasks/StreamTask.java | 9 ++++--
.../streaming/runtime/tasks/StreamTaskTest.java | 37 ++++++++++++++++++++++
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/flink-streaming-java/src/main/java/org/apache/flink/streaming/runtime/tasks/StreamTask.java b/flink-streaming-java/src/main/java/org/apache/flink/streaming/runtime/tasks/StreamTask.java
index 6b52ed5da3b..d2d903fc33a 100644
--- a/flink-streaming-java/src/main/java/org/apache/flink/streaming/runtime/tasks/StreamTask.java
+++ b/flink-streaming-java/src/main/java/org/apache/flink/streaming/runtime/tasks/StreamTask.java
@@ -258,6 +258,9 @@ public abstract class StreamTask<OUT, OP extends StreamOperator<OUT>>
*/
private volatile boolean isRunning;
+ /** Flag to mark the task at restoring duration in {@link #restore()}. */
+ private volatile boolean isRestoring;
+
/** Flag to mark this task as canceled. */
private volatile boolean canceled;
@@ -677,6 +680,7 @@ public abstract class StreamTask<OUT, OP extends StreamOperator<OUT>>
LOG.debug("Re-restore attempt rejected.");
return;
}
+ isRestoring = true;
closedOperators = false;
LOG.debug("Initializing {}.", getName());
@@ -718,6 +722,7 @@ public abstract class StreamTask<OUT, OP extends StreamOperator<OUT>>
channelIOExecutor.shutdown();
isRunning = true;
+ isRestoring = false;
}
private CompletableFuture<Void> restoreGates() throws Exception {
@@ -1551,8 +1556,8 @@ public abstract class StreamTask<OUT, OP extends StreamOperator<OUT>>
*/
@Override
public void handleAsyncException(String message, Throwable exception) {
- if (isRunning) {
- // only fail if the task is still running
+ if (isRestoring || isRunning) {
+ // only fail if the task is still in restoring or running
asyncExceptionHandler.handleAsyncException(message, exception);
}
}
diff --git a/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/tasks/StreamTaskTest.java b/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/tasks/StreamTaskTest.java
index 51724eb3113..585cd51ee17 100644
--- a/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/tasks/StreamTaskTest.java
+++ b/flink-streaming-java/src/test/java/org/apache/flink/streaming/runtime/tasks/StreamTaskTest.java
@@ -402,6 +402,43 @@ public class StreamTaskTest {
}
}
+ @Test
+ void testHandleAsyncExceptionDuringRestoring() throws Exception {
+ MockEnvironment mockEnvironment = MockEnvironment.builder().build();
+ Throwable expectedException = new RuntimeException("RUNTIME EXCEPTION");
+
+ mockEnvironment.setExpectedExternalFailureCause(AsynchronousException.class);
+ final String expectedErrorMessage = "EXPECTED_ERROR MESSAGE";
+
+ StreamTaskITCase.NoOpStreamTask initThrowExceptionTask =
+ new StreamTaskITCase.NoOpStreamTask(mockEnvironment) {
+
+ @Override
+ protected void init() throws Exception {
+ super.init();
+
+ // Throw exception during restoring.
+ CompletableFuture.runAsync(
+ () ->
+ this.handleAsyncException(
+ expectedErrorMessage, expectedException))
+ .get();
+ }
+ };
+ initThrowExceptionTask.restore();
+
+ Optional<? extends Throwable> actualExternalFailureCause =
+ mockEnvironment.getActualExternalFailureCause();
+ final Throwable actualException =
+ actualExternalFailureCause.orElseThrow(
+ () -> new AssertionError("Expected exceptional completion"));
+
+ assertThat(actualException)
+ .isInstanceOf(AsynchronousException.class)
+ .hasMessage(expectedErrorMessage)
+ .hasCause(expectedException);
+ }
+
/**
* This test checks the async exceptions handling wraps the message and cause as an
* AsynchronousException and propagates this to the environment.