2020import org .apache .dolphinscheduler .common .enums .CommandType ;
2121import org .apache .dolphinscheduler .common .enums .WorkflowExecutionStatus ;
2222import org .apache .dolphinscheduler .dao .entity .Command ;
23- import org .apache .dolphinscheduler .dao .entity .TaskInstance ;
2423import org .apache .dolphinscheduler .dao .entity .WorkflowInstance ;
25- import org .apache .dolphinscheduler .dao .repository .TaskInstanceDao ;
2624import org .apache .dolphinscheduler .dao .repository .WorkflowInstanceDao ;
27- import org .apache .dolphinscheduler .plugin .task .api .enums .TaskExecutionStatus ;
2825import org .apache .dolphinscheduler .server .master .config .MasterConfig ;
29- import org .apache .dolphinscheduler .server .master .engine .graph .IWorkflowExecutionGraphAssembler ;
30- import org .apache .dolphinscheduler .server .master .engine .graph .IWorkflowGraph ;
31- import org .apache .dolphinscheduler .server .master .engine .graph .WorkflowExecutionGraph ;
32- import org .apache .dolphinscheduler .server .master .engine .graph .WorkflowGraphTopologyLogicalVisitor ;
33- import org .apache .dolphinscheduler .server .master .engine .task .runnable .TaskExecutionRunnable ;
34- import org .apache .dolphinscheduler .server .master .engine .task .runnable .TaskExecutionRunnableBuilder ;
35- import org .apache .dolphinscheduler .server .master .engine .task .runnable .TaskInstanceFactories ;
3626import org .apache .dolphinscheduler .server .master .runner .WorkflowExecuteContext .WorkflowExecuteContextBuilder ;
3727
38- import java .util .ArrayList ;
39- import java .util .HashSet ;
40- import java .util .List ;
41- import java .util .Map ;
42- import java .util .Set ;
43- import java .util .function .BiConsumer ;
44- import java .util .function .Function ;
45- import java .util .stream .Collectors ;
46-
4728import org .springframework .beans .factory .annotation .Autowired ;
48- import org .springframework .context .ApplicationContext ;
4929import org .springframework .stereotype .Component ;
5030
51- import com .google .common .collect .Lists ;
52-
5331/**
5432 * This handler used to handle {@link CommandType#START_FAILURE_TASK_PROCESS}.
5533 * <p> Will start the failure/pause/killed and other task instance which is behind success tasks instance but not been triggered.
@@ -60,15 +38,6 @@ public class RecoverFailureTaskCommandHandler extends AbstractCommandHandler {
6038 @ Autowired
6139 private WorkflowInstanceDao workflowInstanceDao ;
6240
63- @ Autowired
64- private TaskInstanceDao taskInstanceDao ;
65-
66- @ Autowired
67- private ApplicationContext applicationContext ;
68-
69- @ Autowired
70- private TaskInstanceFactories taskInstanceFactories ;
71-
7241 @ Autowired
7342 private MasterConfig masterConfig ;
7443
@@ -101,146 +70,6 @@ protected void assembleWorkflowInstance(
10170 workflowExecuteContextBuilder .setWorkflowInstance (workflowInstance );
10271 }
10372
104- @ Override
105- protected IWorkflowExecutionGraphAssembler createWorkflowExecutionGraphAssembler (
106- final WorkflowExecuteContextBuilder workflowExecuteContextBuilder ) {
107- // Capture the context needed for deferred graph assembly
108- final IWorkflowGraph workflowGraph = workflowExecuteContextBuilder .getWorkflowGraph ();
109- final WorkflowInstance workflowInstance = workflowExecuteContextBuilder .getWorkflowInstance ();
110- final List <String > startNodes = parseStartNodesFromWorkflowInstance (workflowExecuteContextBuilder );
111-
112- return () -> {
113- final Map <String , TaskInstance > taskInstanceMap = dealWithHistoryTaskInstances (
114- workflowExecuteContextBuilder )
115- .stream ()
116- .collect (Collectors .toMap (TaskInstance ::getName , Function .identity ()));
117-
118- final WorkflowExecutionGraph workflowExecutionGraph = new WorkflowExecutionGraph ();
119-
120- final BiConsumer <String , Set <String >> taskExecutionRunnableCreator = (task , successors ) -> {
121- final TaskExecutionRunnableBuilder taskExecutionRunnableBuilder =
122- TaskExecutionRunnableBuilder
123- .builder ()
124- .workflowExecutionGraph (workflowExecutionGraph )
125- .workflowDefinition (workflowExecuteContextBuilder .getWorkflowDefinition ())
126- .project (workflowExecuteContextBuilder .getProject ())
127- .workflowInstance (workflowInstance )
128- .taskDefinition (workflowGraph .getTaskNodeByName (task ))
129- .taskInstance (taskInstanceMap .get (task ))
130- .workflowEventBus (workflowExecuteContextBuilder .getWorkflowEventBus ())
131- .applicationContext (applicationContext )
132- .build ();
133- workflowExecutionGraph .addNode (new TaskExecutionRunnable (taskExecutionRunnableBuilder ));
134- workflowExecutionGraph .addEdge (task , successors );
135- };
136-
137- final WorkflowGraphTopologyLogicalVisitor workflowGraphTopologyLogicalVisitor =
138- WorkflowGraphTopologyLogicalVisitor .builder ()
139- .taskDependType (workflowInstance .getTaskDependType ())
140- .onWorkflowGraph (workflowGraph )
141- .fromTask (startNodes )
142- .doVisitFunction (taskExecutionRunnableCreator )
143- .build ();
144- workflowGraphTopologyLogicalVisitor .visit ();
145- workflowExecutionGraph .removeUnReachableEdge ();
146-
147- return workflowExecutionGraph ;
148- };
149- }
150-
151- /**
152- * Return the valid task instance which should not be recovered.
153- * <p> Will mark the failure/killed task instance as invalid.
154- */
155- private List <TaskInstance > dealWithHistoryTaskInstances (
156- final WorkflowExecuteContextBuilder workflowExecuteContextBuilder ) {
157- final WorkflowInstance workflowInstance = workflowExecuteContextBuilder .getWorkflowInstance ();
158- final Map <String , TaskInstance > taskInstanceMap = super .getValidTaskInstance (workflowInstance )
159- .stream ()
160- .collect (Collectors .toMap (TaskInstance ::getName , Function .identity ()));
161-
162- final IWorkflowGraph workflowGraph = workflowExecuteContextBuilder .getWorkflowGraph ();
163-
164- final Set <String > needRecoverTasks = new HashSet <>();
165- final Set <String > markInvalidTasks = new HashSet <>();
166- final BiConsumer <String , Set <String >> historyTaskInstanceMarker = (task , successors ) -> {
167- // If the parent is need recover
168- // Then the task should mark as invalid, and it's child should be mark as invalidated.
169- if (markInvalidTasks .contains (task )) {
170- if (taskInstanceMap .containsKey (task )) {
171- taskInstanceDao .markTaskInstanceInvalid (Lists .newArrayList (taskInstanceMap .get (task )));
172- taskInstanceMap .remove (task );
173- }
174- markInvalidTasks .addAll (successors );
175- return ;
176- }
177-
178- final TaskInstance taskInstance = taskInstanceMap .get (task );
179- if (taskInstance == null ) {
180- return ;
181- }
182-
183- if (isTaskNeedRecreate (taskInstance ) || isTaskCanRecover (taskInstance )) {
184- needRecoverTasks .add (task );
185- markInvalidTasks .addAll (successors );
186- }
187- };
188-
189- final WorkflowGraphTopologyLogicalVisitor workflowGraphTopologyLogicalVisitor =
190- WorkflowGraphTopologyLogicalVisitor .builder ()
191- .onWorkflowGraph (workflowGraph )
192- .taskDependType (workflowInstance .getTaskDependType ())
193- .fromTask (parseStartNodesFromWorkflowInstance (workflowExecuteContextBuilder ))
194- .doVisitFunction (historyTaskInstanceMarker )
195- .build ();
196- workflowGraphTopologyLogicalVisitor .visit ();
197-
198- for (String task : needRecoverTasks ) {
199- final TaskInstance taskInstance = taskInstanceMap .get (task );
200- if (isTaskCanRecover (taskInstance )) {
201- taskInstanceMap .put (task , createRecoverTaskInstance (taskInstance ));
202- continue ;
203- }
204- if (isTaskNeedRecreate (taskInstance )) {
205- taskInstanceMap .put (task , createRecreatedTaskInstance (taskInstance ));
206- }
207- }
208- return new ArrayList <>(taskInstanceMap .values ());
209- }
210-
211- /**
212- * Whether the task need to be recreated.
213- * <p> If the task state is FAILURE and KILL, then will mark the task invalid and recreate the task.
214- */
215- private boolean isTaskNeedRecreate (final TaskInstance taskInstance ) {
216- if (taskInstance == null ) {
217- return false ;
218- }
219- return taskInstance .getState () == TaskExecutionStatus .FAILURE
220- || taskInstance .getState () == TaskExecutionStatus .KILL ;
221- }
222-
223- private TaskInstance createRecreatedTaskInstance (final TaskInstance taskInstance ) {
224- return taskInstanceFactories .failedRecoverTaskInstanceFactory ()
225- .builder ()
226- .withTaskInstance (taskInstance )
227- .build ();
228- }
229-
230- private boolean isTaskCanRecover (final TaskInstance taskInstance ) {
231- if (taskInstance == null ) {
232- return false ;
233- }
234- return taskInstance .getState () == TaskExecutionStatus .PAUSE ;
235- }
236-
237- private TaskInstance createRecoverTaskInstance (final TaskInstance taskInstance ) {
238- return taskInstanceFactories .pauseRecoverTaskInstanceFactory ()
239- .builder ()
240- .withTaskInstance (taskInstance )
241- .build ();
242- }
243-
24473 @ Override
24574 public CommandType commandType () {
24675 return CommandType .START_FAILURE_TASK_PROCESS ;
0 commit comments