conductor-oss / conductor-oss/conductor
[FEATURE]: Support system tasks other than the SubWorkflow task as parent of a Sub Workflow
- Dominant language
- Java
- Stars
- 32.2k
- Forks
- 1k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 37
Description
## Describe the Feature Request
I have been working on an custom system task that launches multiple SubWorkflows in a loop. However, I found there were a number of places with logic hardcoded to taskType that prevented this working.
There are hardcoded references to SUB_WORKFLOW in the following places methods:
1. `WorkflowExecutorOps.executeSubworkflowTaskAndSyncData` called from `updateParentWorkflowTask`
```
@VisibleForTesting
void updateParentWorkflowTask(WorkflowModel subWorkflow) {
TaskModel subWorkflowTask =
executionDAOFacade.getTaskModel(subWorkflow.getParentWorkflowTaskId());
executeSubworkflowTaskAndSyncData(subWorkflow, subWorkflowTask);
executionDAOFacade.updateTask(subWorkflowTask);
}
private void executeSubworkflowTaskAndSyncData(
WorkflowModel subWorkflow, TaskModel subWorkflowTask) {
WorkflowSystemTask subWorkflowSystemTask =
systemTaskRegistry.get(TaskType.TASK_TYPE_SUB_WORKFLOW);
subWorkflowSystemTask.execute(subWorkflow, subWorkflowTask, this);
}
```
2. `WorkflowExecutorOps.findChangedSubWorkflowTask`
- note the initial filtering here might be a bug assuming DYNAMIC_TASK could also run a SubWorkflow task
```
if (workflowDef.containsType(TaskType.TASK_TYPE_SUB_WORKFLOW)
|| workflow.getWorkflowDefinition()
.containsType(TaskType.TASK_TYPE_FORK_JOIN_DYNAMIC)) {
return workflow.getTasks().stream()
.filter(
t ->
t.getTaskType().equals(TaskType.TASK_TYPE_SUB_WORKFLOW)
&& t.isSubworkflowChanged()
&& !t.isRetried())
.findFirst();
}
```
3. `WorkflowExecutorOps.rerunWF` (line 1669 & 1772)
4. `WorkflowExecutorOps.findLastFailedSubWorkflowIfAny` (line 413)
5. `WorkflowRepairService.verifyAndRepairTask` (line 154)
## Describe Preferred Solution
1. Change the `WorkflowExecutorOps.executeSubworkflowTaskAndSyncData` to pass`subWorkflowTask.getTaskType()` to the `systemTaskRegistry`
```
private void executeSubworkflowTaskAndSyncData(
WorkflowModel subWorkflow, TaskModel subWorkflowTask) {
WorkflowSystemTask subWorkflowSystemTask =
systemTaskRegistry.get(subWorkflowTask.getTaskType()); // replace hard coding here
subWorkflowSystemTask.execute(subWorkflow, subWorkflowTask, this);
}
```
2. And the following method to `WorkflowSystemTask` interface and override to return true in `SubWorkflow` class:
```
public boolean isSubWorkflowParent() { return false; }
```
Add additional method to `SystemTaskRegistry`
```
public boolean isSubWorkflowParent(String taskType) {
return get(taskType).isSubWorkflowParent();
}
```
3. Replace logic that explicitly checks for hardcoding with checks on the SystemRegistry
``
systemTaskRegistry.isSubWorkflowParent(t.getTaskType())
```
## Describe Alternatives
I am not aware of other viable options, as the task type still needs to be unique
Contributor guide
Assessment
This issue has not been assessed yet.