This is an automated email from the ASF dual-hosted git repository.
SbloodyS pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 1f71cfcbd9 [Fix-18406] Fix task instance failed but workflow instance
remains in running state while using continue strategy with a blocked
intermediate predecessor (#18415)
1f71cfcbd9 is described below
commit 1f71cfcbd9f983ccaed48f2ffeb849f7e0eb2fd6
Author: xiangzihao <[email protected]>
AuthorDate: Wed Jul 15 17:55:11 2026 +0800
[Fix-18406] Fix task instance failed but workflow instance remains in
running state while using continue strategy with a blocked intermediate
predecessor (#18415)
---
.../statemachine/AbstractWorkflowStateAction.java | 10 +-
.../cases/WorkflowStartGraphTestCase.java | 40 ++++++
...redecessor_using_failure_strategy_continue.yaml | 153 +++++++++++++++++++++
3 files changed, 202 insertions(+), 1 deletion(-)
diff --git
a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/workflow/statemachine/AbstractWorkflowStateAction.java
b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/workflow/statemachine/AbstractWorkflowStateAction.java
index 48b329bc77..b243b7b1e0 100644
---
a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/workflow/statemachine/AbstractWorkflowStateAction.java
+++
b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/engine/workflow/statemachine/AbstractWorkflowStateAction.java
@@ -94,7 +94,15 @@ public abstract class AbstractWorkflowStateAction implements
IWorkflowStateActio
.getPredecessors(taskExecution.getName())
.stream())
.allMatch(workflowExecutionGraph::isTaskExecutionInActive);
- if (isAllCandidateTaskPredecessorsInActive) {
+ final boolean isAllTaskExecutionChainFinish =
workflowExecutionGraph.isAllTaskExecutionChainFinish();
+ if (isAllCandidateTaskPredecessorsInActive ||
isAllTaskExecutionChainFinish) {
+ log.debug("No candidate task can be triggered in workflow: {},
check whether the workflow can finish, "
+ + "allCandidateTaskPredecessorsInActive: {},
allTaskExecutionChainFinish: {}, "
+ + "candidateTasks: {}",
+ workflowExecution.getName(),
+ isAllCandidateTaskPredecessorsInActive,
+ isAllTaskExecutionChainFinish,
+
triggerCandidateTasks.stream().map(ITaskExecution::getName).collect(Collectors.toList()));
emitWorkflowFinishedEventIfApplicable(workflowExecution);
}
return;
diff --git
a/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/integration/cases/WorkflowStartGraphTestCase.java
b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/integration/cases/WorkflowStartGraphTestCase.java
index c3b9137e43..c105112457 100644
---
a/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/integration/cases/WorkflowStartGraphTestCase.java
+++
b/dolphinscheduler-master/src/test/java/org/apache/dolphinscheduler/server/master/integration/cases/WorkflowStartGraphTestCase.java
@@ -209,6 +209,46 @@ public class WorkflowStartGraphTestCase extends
AbstractMasterIntegrationTestCas
masterContainer.assertAllResourceReleased();
}
+ @Test
+ @DisplayName("Test continue failure strategy with a blocked intermediate
predecessor")
+ void
testStartWorkflow_with_blockedIntermediatePredecessor_usingFailureStrategyContinue()
{
+ final String yaml =
+
"/it/start/workflow_with_blocked_intermediate_predecessor_using_failure_strategy_continue.yaml";
+ final WorkflowTestCaseContext context =
workflowTestCaseContextFactory.initializeContextFromYaml(yaml);
+ final WorkflowDefinition workflow = context.getOneWorkflow();
+
+ final WorkflowOperator.WorkflowTriggerDTO workflowTriggerDTO =
WorkflowOperator.WorkflowTriggerDTO.builder()
+ .workflowDefinition(workflow)
+ .runWorkflowCommandParam(new RunWorkflowCommandParam())
+ .failureStrategy(FailureStrategy.CONTINUE)
+ .build();
+ final Integer workflowInstanceId =
workflowOperator.manualTriggerWorkflow(workflowTriggerDTO);
+
+ await()
+ .atMost(Duration.ofMinutes(1))
+ .untilAsserted(() -> {
+
Assertions.assertThat(repository.queryWorkflowInstance(workflowInstanceId))
+ .matches(workflowInstance ->
workflowInstance.getState() == WorkflowExecutionStatus.FAILURE)
+ .matches(workflowInstance ->
workflowInstance.getEndTime() != null);
+
+
Assertions.assertThat(repository.queryTaskInstance(workflowInstanceId))
+ .hasSize(3)
+ .anySatisfy(taskInstance -> {
+
assertThat(taskInstance.getName()).isEqualTo("A");
+
assertThat(taskInstance.getState()).isEqualTo(TaskExecutionStatus.SUCCESS);
+ })
+ .anySatisfy(taskInstance -> {
+
assertThat(taskInstance.getName()).isEqualTo("B");
+
assertThat(taskInstance.getState()).isEqualTo(TaskExecutionStatus.SUCCESS);
+ })
+ .anySatisfy(taskInstance -> {
+
assertThat(taskInstance.getName()).isEqualTo("C");
+
assertThat(taskInstance.getState()).isEqualTo(TaskExecutionStatus.FAILURE);
+ });
+ });
+ masterContainer.assertAllResourceReleased();
+ }
+
@Test
@DisplayName("Test start a workflow with two parallel fake tasks(A, B)
success")
public void testStartWorkflow_with_twoParallelSuccessTask() {
diff --git
a/dolphinscheduler-master/src/test/resources/it/start/workflow_with_blocked_intermediate_predecessor_using_failure_strategy_continue.yaml
b/dolphinscheduler-master/src/test/resources/it/start/workflow_with_blocked_intermediate_predecessor_using_failure_strategy_continue.yaml
new file mode 100644
index 0000000000..87ce533df0
--- /dev/null
+++
b/dolphinscheduler-master/src/test/resources/it/start/workflow_with_blocked_intermediate_predecessor_using_failure_strategy_continue.yaml
@@ -0,0 +1,153 @@
+#
+# 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.
+#
+
+# A(success) -> B(success) -> E(not triggered)
+# C(failed) -> D(not triggered) -> E(not triggered)
+# C finishes before A.
+project:
+ name: MasterIntegrationTest
+ code: 1
+ description: This is a fake project
+ userId: 1
+ userName: admin
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+
+workflows:
+ - name:
workflow_with_blocked_intermediate_predecessor_using_failure_strategy_continue
+ code: 1
+ version: 1
+ projectCode: 1
+ description: This is a fake workflow with a blocked intermediate
predecessor
+ releaseState: ONLINE
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+ userId: 1
+ executionType: PARALLEL
+
+tasks:
+ - name: A
+ code: 1
+ version: 1
+ projectCode: 1
+ userId: 1
+ taskType: LogicFakeTask
+ taskParams: '{"localParams":null,"varPool":[],"shellScript":"sleep 1"}'
+ workerGroup: default
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+ taskExecuteType: BATCH
+ - name: B
+ code: 2
+ version: 1
+ projectCode: 1
+ userId: 1
+ taskType: LogicFakeTask
+ taskParams: '{"localParams":null,"varPool":[],"shellScript":"sleep 1"}'
+ workerGroup: default
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+ taskExecuteType: BATCH
+ - name: C
+ code: 3
+ version: 1
+ projectCode: 1
+ userId: 1
+ taskType: LogicFakeTask
+ taskParams: '{"localParams":null,"varPool":[],"shellScript":"xx"}'
+ workerGroup: default
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+ taskExecuteType: BATCH
+ - name: D
+ code: 4
+ version: 1
+ projectCode: 1
+ userId: 1
+ taskType: LogicFakeTask
+ taskParams: '{"localParams":null,"varPool":[],"shellScript":"echo
success"}'
+ workerGroup: default
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+ taskExecuteType: BATCH
+ - name: E
+ code: 5
+ version: 1
+ projectCode: 1
+ userId: 1
+ taskType: LogicFakeTask
+ taskParams: '{"localParams":null,"varPool":[],"shellScript":"echo
success"}'
+ workerGroup: default
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2021-08-12 00:00:00
+ taskExecuteType: BATCH
+
+taskRelations:
+ - projectCode: 1
+ workflowDefinitionCode: 1
+ workflowDefinitionVersion: 1
+ preTaskCode: 0
+ preTaskVersion: 0
+ postTaskCode: 1
+ postTaskVersion: 1
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2024-08-12 00:00:00
+ - projectCode: 1
+ workflowDefinitionCode: 1
+ workflowDefinitionVersion: 1
+ preTaskCode: 0
+ preTaskVersion: 0
+ postTaskCode: 3
+ postTaskVersion: 1
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2024-08-12 00:00:00
+ - projectCode: 1
+ workflowDefinitionCode: 1
+ workflowDefinitionVersion: 1
+ preTaskCode: 1
+ preTaskVersion: 1
+ postTaskCode: 2
+ postTaskVersion: 1
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2024-08-12 00:00:00
+ - projectCode: 1
+ workflowDefinitionCode: 1
+ workflowDefinitionVersion: 1
+ preTaskCode: 3
+ preTaskVersion: 1
+ postTaskCode: 4
+ postTaskVersion: 1
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2024-08-12 00:00:00
+ - projectCode: 1
+ workflowDefinitionCode: 1
+ workflowDefinitionVersion: 1
+ preTaskCode: 2
+ preTaskVersion: 1
+ postTaskCode: 5
+ postTaskVersion: 1
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2024-08-12 00:00:00
+ - projectCode: 1
+ workflowDefinitionCode: 1
+ workflowDefinitionVersion: 1
+ preTaskCode: 4
+ preTaskVersion: 1
+ postTaskCode: 5
+ postTaskVersion: 1
+ createTime: 2024-08-12 00:00:00
+ updateTime: 2024-08-12 00:00:00