|
@@ -216,19 +216,19 @@ public class WorkflowExecuteThread {
|
|
|
/**
|
|
|
* constructor of WorkflowExecuteThread
|
|
|
*
|
|
|
- * @param processInstance processInstance
|
|
|
- * @param processService processService
|
|
|
- * @param nettyExecutorManager nettyExecutorManager
|
|
|
- * @param processAlertManager processAlertManager
|
|
|
- * @param masterConfig masterConfig
|
|
|
+ * @param processInstance processInstance
|
|
|
+ * @param processService processService
|
|
|
+ * @param nettyExecutorManager nettyExecutorManager
|
|
|
+ * @param processAlertManager processAlertManager
|
|
|
+ * @param masterConfig masterConfig
|
|
|
* @param stateWheelExecuteThread stateWheelExecuteThread
|
|
|
*/
|
|
|
public WorkflowExecuteThread(ProcessInstance processInstance
|
|
|
- , ProcessService processService
|
|
|
- , NettyExecutorManager nettyExecutorManager
|
|
|
- , ProcessAlertManager processAlertManager
|
|
|
- , MasterConfig masterConfig
|
|
|
- , StateWheelExecuteThread stateWheelExecuteThread) {
|
|
|
+ , ProcessService processService
|
|
|
+ , NettyExecutorManager nettyExecutorManager
|
|
|
+ , ProcessAlertManager processAlertManager
|
|
|
+ , MasterConfig masterConfig
|
|
|
+ , StateWheelExecuteThread stateWheelExecuteThread) {
|
|
|
this.processService = processService;
|
|
|
this.processInstance = processInstance;
|
|
|
this.masterConfig = masterConfig;
|
|
@@ -265,14 +265,14 @@ public class WorkflowExecuteThread {
|
|
|
|
|
|
public String getKey() {
|
|
|
if (StringUtils.isNotEmpty(key)
|
|
|
- || this.processDefinition == null) {
|
|
|
+ || this.processDefinition == null) {
|
|
|
return key;
|
|
|
}
|
|
|
|
|
|
key = String.format("%d_%d_%d",
|
|
|
- this.processDefinition.getCode(),
|
|
|
- this.processDefinition.getVersion(),
|
|
|
- this.processInstance.getId());
|
|
|
+ this.processDefinition.getCode(),
|
|
|
+ this.processDefinition.getVersion(),
|
|
|
+ this.processInstance.getId());
|
|
|
return key;
|
|
|
}
|
|
|
|
|
@@ -400,7 +400,7 @@ public class WorkflowExecuteThread {
|
|
|
} else {
|
|
|
ProcessInstance processInstance = this.processService.findProcessInstanceById(nextTaskInstance.getProcessInstanceId());
|
|
|
this.processService.sendStartTask2Master(processInstance, nextTaskInstance.getId(),
|
|
|
- org.apache.dolphinscheduler.remote.command.CommandType.TASK_WAKEUP_EVENT_REQUEST);
|
|
|
+ org.apache.dolphinscheduler.remote.command.CommandType.TASK_WAKEUP_EVENT_REQUEST);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -420,19 +420,19 @@ public class WorkflowExecuteThread {
|
|
|
|
|
|
private void taskFinished(TaskInstance task) {
|
|
|
logger.info("work flow {} task {} state:{} ",
|
|
|
- processInstance.getId(),
|
|
|
- task.getId(),
|
|
|
- task.getState());
|
|
|
+ processInstance.getId(),
|
|
|
+ task.getId(),
|
|
|
+ task.getState());
|
|
|
if (task.taskCanRetry()) {
|
|
|
addTaskToStandByList(task);
|
|
|
if (!task.retryTaskIntervalOverTime()) {
|
|
|
logger.info("failure task will be submitted: process id: {}, task instance id: {} state:{} retry times:{} / {}, interval:{}",
|
|
|
- processInstance.getId(),
|
|
|
- task.getId(),
|
|
|
- task.getState(),
|
|
|
- task.getRetryTimes(),
|
|
|
- task.getMaxRetryTimes(),
|
|
|
- task.getRetryInterval());
|
|
|
+ processInstance.getId(),
|
|
|
+ task.getId(),
|
|
|
+ task.getState(),
|
|
|
+ task.getRetryTimes(),
|
|
|
+ task.getMaxRetryTimes(),
|
|
|
+ task.getRetryInterval());
|
|
|
stateWheelExecuteThread.addTask4TimeoutCheck(task);
|
|
|
stateWheelExecuteThread.addTask4RetryCheck(task);
|
|
|
} else {
|
|
@@ -454,7 +454,7 @@ public class WorkflowExecuteThread {
|
|
|
submitPostNode(Long.toString(task.getTaskCode()));
|
|
|
} else if (task.getState().typeIsFailure()) {
|
|
|
if (task.isConditionsTask()
|
|
|
- || DagHelper.haveConditionsAfterNode(Long.toString(task.getTaskCode()), dag)) {
|
|
|
+ || DagHelper.haveConditionsAfterNode(Long.toString(task.getTaskCode()), dag)) {
|
|
|
submitPostNode(Long.toString(task.getTaskCode()));
|
|
|
} else {
|
|
|
errorTaskMap.put(Long.toString(task.getTaskCode()), task.getId());
|
|
@@ -473,7 +473,7 @@ public class WorkflowExecuteThread {
|
|
|
logger.info("process instance update: {}", processInstanceId);
|
|
|
processInstance = processService.findProcessInstanceById(processInstanceId);
|
|
|
processDefinition = processService.findProcessDefinition(processInstance.getProcessDefinitionCode(),
|
|
|
- processInstance.getProcessDefinitionVersion());
|
|
|
+ processInstance.getProcessDefinitionVersion());
|
|
|
processInstance.setProcessDefinition(processDefinition);
|
|
|
}
|
|
|
|
|
@@ -502,8 +502,8 @@ public class WorkflowExecuteThread {
|
|
|
public boolean checkProcessInstance(StateEvent stateEvent) {
|
|
|
if (this.processInstance.getId() != stateEvent.getProcessInstanceId()) {
|
|
|
logger.error("mismatch process instance id: {}, state event:{}",
|
|
|
- this.processInstance.getId(),
|
|
|
- stateEvent);
|
|
|
+ this.processInstance.getId(),
|
|
|
+ stateEvent);
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
@@ -603,9 +603,9 @@ public class WorkflowExecuteThread {
|
|
|
return true;
|
|
|
}
|
|
|
logger.info("process complement continue. process id:{}, schedule time:{} complementListDate:{}",
|
|
|
- processInstance.getId(),
|
|
|
- processInstance.getScheduleTime(),
|
|
|
- complementListDate.toString());
|
|
|
+ processInstance.getId(),
|
|
|
+ processInstance.getScheduleTime(),
|
|
|
+ complementListDate.toString());
|
|
|
scheduleDate = complementListDate.get(index + 1);
|
|
|
//the next process complement
|
|
|
processInstance.setId(0);
|
|
@@ -619,9 +619,9 @@ public class WorkflowExecuteThread {
|
|
|
|
|
|
processInstance.setState(ExecutionStatus.RUNNING_EXECUTION);
|
|
|
processInstance.setGlobalParams(ParameterUtils.curingGlobalParams(
|
|
|
- processDefinition.getGlobalParamMap(),
|
|
|
- processDefinition.getGlobalParamList(),
|
|
|
- CommandType.COMPLEMENT_DATA, processInstance.getScheduleTime()));
|
|
|
+ processDefinition.getGlobalParamMap(),
|
|
|
+ processDefinition.getGlobalParamList(),
|
|
|
+ CommandType.COMPLEMENT_DATA, processInstance.getScheduleTime()));
|
|
|
processInstance.setStartTime(new Date());
|
|
|
processInstance.setEndTime(null);
|
|
|
processService.saveProcessInstance(processInstance);
|
|
@@ -632,7 +632,7 @@ public class WorkflowExecuteThread {
|
|
|
|
|
|
private boolean needComplementProcess() {
|
|
|
if (processInstance.isComplementData()
|
|
|
- && Flag.NO == processInstance.getIsSubProcess()) {
|
|
|
+ && Flag.NO == processInstance.getIsSubProcess()) {
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
@@ -709,7 +709,7 @@ public class WorkflowExecuteThread {
|
|
|
return;
|
|
|
}
|
|
|
processDefinition = processService.findProcessDefinition(processInstance.getProcessDefinitionCode(),
|
|
|
- processInstance.getProcessDefinitionVersion());
|
|
|
+ processInstance.getProcessDefinitionVersion());
|
|
|
processInstance.setProcessDefinition(processDefinition);
|
|
|
|
|
|
List<TaskInstance> recoverNodeList = getStartTaskInstanceList(processInstance.getCommandParam());
|
|
@@ -729,7 +729,7 @@ public class WorkflowExecuteThread {
|
|
|
List<String> recoveryNodeCodeList = getRecoveryNodeCodeList(recoverNodeList);
|
|
|
List<String> startNodeNameList = parseStartNodeName(processInstance.getCommandParam());
|
|
|
ProcessDag processDag = generateFlowDag(taskNodeList,
|
|
|
- startNodeNameList, recoveryNodeCodeList, processInstance.getTaskDependType());
|
|
|
+ startNodeNameList, recoveryNodeCodeList, processInstance.getTaskDependType());
|
|
|
if (processDag == null) {
|
|
|
logger.error("processDag is null");
|
|
|
return;
|
|
@@ -776,14 +776,14 @@ public class WorkflowExecuteThread {
|
|
|
if (complementListDate.size() == 0 && needComplementProcess()) {
|
|
|
complementListDate = CronUtils.getSelfFireDateList(start, end, schedules);
|
|
|
logger.info(" process definition code:{} complement data: {}",
|
|
|
- processInstance.getProcessDefinitionCode(), complementListDate.toString());
|
|
|
+ processInstance.getProcessDefinitionCode(), complementListDate.toString());
|
|
|
|
|
|
if (complementListDate.size() > 0 && Flag.NO == processInstance.getIsSubProcess()) {
|
|
|
processInstance.setScheduleTime(complementListDate.get(0));
|
|
|
processInstance.setGlobalParams(ParameterUtils.curingGlobalParams(
|
|
|
- processDefinition.getGlobalParamMap(),
|
|
|
- processDefinition.getGlobalParamList(),
|
|
|
- CommandType.COMPLEMENT_DATA, processInstance.getScheduleTime()));
|
|
|
+ processDefinition.getGlobalParamMap(),
|
|
|
+ processDefinition.getGlobalParamList(),
|
|
|
+ CommandType.COMPLEMENT_DATA, processInstance.getScheduleTime()));
|
|
|
processService.updateProcessInstance(processInstance);
|
|
|
}
|
|
|
}
|
|
@@ -801,7 +801,7 @@ public class WorkflowExecuteThread {
|
|
|
try {
|
|
|
ITaskProcessor taskProcessor = TaskProcessorFactory.getTaskProcessor(taskInstance.getTaskType());
|
|
|
if (taskInstance.getState() == ExecutionStatus.RUNNING_EXECUTION
|
|
|
- && taskProcessor.getType().equalsIgnoreCase(Constants.COMMON_TASK_TYPE)) {
|
|
|
+ && taskProcessor.getType().equalsIgnoreCase(Constants.COMMON_TASK_TYPE)) {
|
|
|
notifyProcessHostUpdate(taskInstance);
|
|
|
}
|
|
|
// package task instance before submit
|
|
@@ -810,8 +810,8 @@ public class WorkflowExecuteThread {
|
|
|
boolean submit = taskProcessor.submit(taskInstance, processInstance, masterConfig.getTaskCommitRetryTimes(), masterConfig.getTaskCommitInterval(), masterConfig.isTaskLogger());
|
|
|
if (!submit) {
|
|
|
logger.error("process id:{} name:{} submit standby task id:{} name:{} failed!",
|
|
|
- processInstance.getId(), processInstance.getName(),
|
|
|
- taskInstance.getId(), taskInstance.getName());
|
|
|
+ processInstance.getId(), processInstance.getName(),
|
|
|
+ taskInstance.getId(), taskInstance.getName());
|
|
|
return null;
|
|
|
}
|
|
|
validTaskMap.put(Long.toString(taskInstance.getTaskCode()), taskInstance.getId());
|
|
@@ -857,7 +857,7 @@ public class WorkflowExecuteThread {
|
|
|
* find task instance in db.
|
|
|
* in case submit more than one same name task in the same time.
|
|
|
*
|
|
|
- * @param taskCode task code
|
|
|
+ * @param taskCode task code
|
|
|
* @param taskVersion task version
|
|
|
* @return TaskInstance
|
|
|
*/
|
|
@@ -875,7 +875,7 @@ public class WorkflowExecuteThread {
|
|
|
* encapsulation task
|
|
|
*
|
|
|
* @param processInstance process instance
|
|
|
- * @param taskNode taskNode
|
|
|
+ * @param taskNode taskNode
|
|
|
* @return TaskInstance
|
|
|
*/
|
|
|
private TaskInstance createTaskInstance(ProcessInstance processInstance, TaskNode taskNode) {
|
|
@@ -1083,34 +1083,51 @@ public class WorkflowExecuteThread {
|
|
|
return DependResult.SUCCESS;
|
|
|
}
|
|
|
TaskNode taskNode = dag.getNode(taskCode);
|
|
|
- List<String> depCodeList = taskNode.getDepList();
|
|
|
- for (String depsNode : depCodeList) {
|
|
|
- if (!dag.containsNode(depsNode)
|
|
|
- || forbiddenTaskMap.containsKey(depsNode)
|
|
|
- || skipTaskNodeMap.containsKey(depsNode)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- // dependencies must be fully completed
|
|
|
- if (!completeTaskMap.containsKey(depsNode)) {
|
|
|
- return DependResult.WAITING;
|
|
|
- }
|
|
|
- Integer depsTaskId = completeTaskMap.get(depsNode);
|
|
|
- ExecutionStatus depTaskState = taskInstanceMap.get(depsTaskId).getState();
|
|
|
- if (depTaskState.typeIsPause() || depTaskState.typeIsCancel()) {
|
|
|
- return DependResult.NON_EXEC;
|
|
|
- }
|
|
|
- // ignore task state if current task is condition
|
|
|
- if (taskNode.isConditionsTask()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (!dependTaskSuccess(depsNode, taskCode)) {
|
|
|
- return DependResult.FAILED;
|
|
|
+ List<String> indirectDepCodeList = new ArrayList<>();
|
|
|
+ setIndirectDepList(taskCode, indirectDepCodeList);
|
|
|
+ for (String depsNode : indirectDepCodeList) {
|
|
|
+ if (dag.containsNode(depsNode) && !skipTaskNodeMap.containsKey(depsNode)) {
|
|
|
+ // dependencies must be fully completed
|
|
|
+ if (!completeTaskMap.containsKey(depsNode)) {
|
|
|
+ return DependResult.WAITING;
|
|
|
+ }
|
|
|
+ Integer depsTaskId = completeTaskMap.get(depsNode);
|
|
|
+ ExecutionStatus depTaskState = taskInstanceMap.get(depsTaskId).getState();
|
|
|
+ if (depTaskState.typeIsPause() || depTaskState.typeIsCancel()) {
|
|
|
+ return DependResult.NON_EXEC;
|
|
|
+ }
|
|
|
+ // ignore task state if current task is condition
|
|
|
+ if (taskNode.isConditionsTask()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!dependTaskSuccess(depsNode, taskCode)) {
|
|
|
+ return DependResult.FAILED;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
logger.info("taskCode: {} completeDependTaskList: {}", taskCode, Arrays.toString(completeTaskMap.keySet().toArray()));
|
|
|
return DependResult.SUCCESS;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * This function is specially used to handle the dependency situation where the parent node is a prohibited node.
|
|
|
+ * When the parent node is a forbidden node, the dependency relationship should continue to be traced
|
|
|
+ *
|
|
|
+ * @param taskCode taskCode
|
|
|
+ * @param indirectDepCodeList All indirectly dependent nodes
|
|
|
+ */
|
|
|
+ private void setIndirectDepList(String taskCode, List<String> indirectDepCodeList) {
|
|
|
+ TaskNode taskNode = dag.getNode(taskCode);
|
|
|
+ List<String> depCodeList = taskNode.getDepList();
|
|
|
+ for (String depsNode : depCodeList) {
|
|
|
+ if (forbiddenTaskMap.containsKey(depsNode)) {
|
|
|
+ setIndirectDepList(depsNode, indirectDepCodeList);
|
|
|
+ } else {
|
|
|
+ indirectDepCodeList.add(depsNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* depend node is completed, but here need check the condition task branch is the next node
|
|
|
*/
|
|
@@ -1156,9 +1173,9 @@ public class WorkflowExecuteThread {
|
|
|
*/
|
|
|
private ExecutionStatus runningState(ExecutionStatus state) {
|
|
|
if (state == ExecutionStatus.READY_STOP
|
|
|
- || state == ExecutionStatus.READY_PAUSE
|
|
|
- || state == ExecutionStatus.WAITING_THREAD
|
|
|
- || state == ExecutionStatus.DELAY_EXECUTION) {
|
|
|
+ || state == ExecutionStatus.READY_PAUSE
|
|
|
+ || state == ExecutionStatus.WAITING_THREAD
|
|
|
+ || state == ExecutionStatus.DELAY_EXECUTION) {
|
|
|
// if the running task is not completed, the state remains unchanged
|
|
|
return state;
|
|
|
} else {
|
|
@@ -1224,8 +1241,8 @@ public class WorkflowExecuteThread {
|
|
|
|
|
|
List<TaskInstance> pauseList = getCompleteTaskByState(ExecutionStatus.PAUSE);
|
|
|
if (CollectionUtils.isNotEmpty(pauseList)
|
|
|
- || !isComplementEnd()
|
|
|
- || readyToSubmitTaskQueue.size() > 0) {
|
|
|
+ || !isComplementEnd()
|
|
|
+ || readyToSubmitTaskQueue.size() > 0) {
|
|
|
return ExecutionStatus.PAUSE;
|
|
|
} else {
|
|
|
return ExecutionStatus.SUCCESS;
|
|
@@ -1264,8 +1281,8 @@ public class WorkflowExecuteThread {
|
|
|
List<TaskInstance> stopList = getCompleteTaskByState(ExecutionStatus.STOP);
|
|
|
List<TaskInstance> killList = getCompleteTaskByState(ExecutionStatus.KILL);
|
|
|
if (CollectionUtils.isNotEmpty(stopList)
|
|
|
- || CollectionUtils.isNotEmpty(killList)
|
|
|
- || !isComplementEnd()) {
|
|
|
+ || CollectionUtils.isNotEmpty(killList)
|
|
|
+ || !isComplementEnd()) {
|
|
|
return ExecutionStatus.STOP;
|
|
|
} else {
|
|
|
return ExecutionStatus.SUCCESS;
|
|
@@ -1318,10 +1335,10 @@ public class WorkflowExecuteThread {
|
|
|
ExecutionStatus state = getProcessInstanceState(processInstance);
|
|
|
if (processInstance.getState() != state) {
|
|
|
logger.info(
|
|
|
- "work flow process instance [id: {}, name:{}], state change from {} to {}, cmd type: {}",
|
|
|
- processInstance.getId(), processInstance.getName(),
|
|
|
- processInstance.getState(), state,
|
|
|
- processInstance.getCommandType());
|
|
|
+ "work flow process instance [id: {}, name:{}], state change from {} to {}, cmd type: {}",
|
|
|
+ processInstance.getId(), processInstance.getName(),
|
|
|
+ processInstance.getState(), state,
|
|
|
+ processInstance.getCommandType());
|
|
|
|
|
|
processInstance.setState(state);
|
|
|
if (state.typeIsFinished()) {
|
|
@@ -1370,14 +1387,14 @@ public class WorkflowExecuteThread {
|
|
|
*/
|
|
|
private void removeTaskFromStandbyList(TaskInstance taskInstance) {
|
|
|
logger.info("remove task from stand by list, id: {} name:{}",
|
|
|
- taskInstance.getId(),
|
|
|
- taskInstance.getName());
|
|
|
+ taskInstance.getId(),
|
|
|
+ taskInstance.getName());
|
|
|
try {
|
|
|
readyToSubmitTaskQueue.remove(taskInstance);
|
|
|
} catch (Exception e) {
|
|
|
logger.error("remove task instance from readyToSubmitTaskQueue error, task id:{}, Name: {}",
|
|
|
- taskInstance.getId(),
|
|
|
- taskInstance.getName(), e);
|
|
|
+ taskInstance.getId(),
|
|
|
+ taskInstance.getName(), e);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1400,7 +1417,7 @@ public class WorkflowExecuteThread {
|
|
|
*/
|
|
|
private void killAllTasks() {
|
|
|
logger.info("kill called on process instance id: {}, num: {}", processInstance.getId(),
|
|
|
- activeTaskProcessorMaps.size());
|
|
|
+ activeTaskProcessorMaps.size());
|
|
|
for (int taskId : activeTaskProcessorMaps.keySet()) {
|
|
|
TaskInstance taskInstance = processService.findTaskInstanceById(taskId);
|
|
|
if (taskInstance == null || taskInstance.getState().typeIsFinished()) {
|
|
@@ -1567,10 +1584,10 @@ public class WorkflowExecuteThread {
|
|
|
/**
|
|
|
* generate flow dag
|
|
|
*
|
|
|
- * @param totalTaskNodeList total task node list
|
|
|
- * @param startNodeNameList start node name list
|
|
|
+ * @param totalTaskNodeList total task node list
|
|
|
+ * @param startNodeNameList start node name list
|
|
|
* @param recoveryNodeCodeList recovery node code list
|
|
|
- * @param depNodeType depend node type
|
|
|
+ * @param depNodeType depend node type
|
|
|
* @return ProcessDag process dag
|
|
|
* @throws Exception exception
|
|
|
*/
|