private boolean rerunWF(
            String workflowId,
            String taskId,
            Map<String, Object> taskInput,
            Map<String, Object> workflowInput,
            String correlationId) {

        // Get the workflow
        WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true);
        if (!workflow.getStatus().isTerminal()) {
            String errorMsg =
                    String.format(
                            "Workflow: %s is not in terminal state, unable to rerun.", workflow);
            LOGGER.error(errorMsg);
            throw new ConflictException(errorMsg);
        }
        updateAndPushParents(workflow, "reran");

        // If the task Id is null it implies that the entire workflow has to be rerun
        if (taskId == null) {
            // remove all tasks
            workflow.getTasks().forEach(task -> executionDAOFacade.removeTask(task.getTaskId()));
            workflow.setTasks(new ArrayList<>());
            // Set workflow as RUNNING
            workflow.setStatus(WorkflowModel.Status.RUNNING);
            // Reset failure reason from previous run to default
            workflow.setReasonForIncompletion(null);
            workflow.setFailedTaskId(null);
            workflow.setFailedReferenceTaskNames(new HashSet<>());
            workflow.setFailedTaskNames(new HashSet<>());

            if (correlationId != null) {
                workflow.setCorrelationId(correlationId);
            }
            if (workflowInput != null) {
                workflow.setInput(workflowInput);
            }

            queueDAO.push(
                    DECIDER_QUEUE,
                    workflow.getWorkflowId(),
                    workflow.getPriority(),
                    properties.getWorkflowOffsetTimeout().getSeconds());
            executionDAOFacade.updateWorkflow(workflow);

            decide(workflowId);
            return true;
        }

        // Now iterate through the tasks and find the "specific" task
        TaskModel rerunFromTask = null;
        for (TaskModel task : workflow.getTasks()) {
            if (task.getTaskId().equals(taskId)) {
                rerunFromTask = task;
                break;
            }
        }

        // If not found look into sub workflows
        if (rerunFromTask == null) {
            for (TaskModel task : workflow.getTasks()) {
                if (task.getTaskType().equalsIgnoreCase(TaskType.TASK_TYPE_SUB_WORKFLOW)) {
                    String subWorkflowId = task.getSubWorkflowId();
                    if (rerunWF(subWorkflowId, taskId, taskInput, null, null)) {
                        rerunFromTask = task;
                        break;
                    }
                }
            }
        }

        if (rerunFromTask != null) {
            // set workflow as RUNNING
            workflow.setStatus(WorkflowModel.Status.RUNNING);
            // Reset failure reason from previous run to default
            workflow.setReasonForIncompletion(null);
            workflow.setFailedTaskId(null);
            workflow.setFailedReferenceTaskNames(new HashSet<>());
            workflow.setFailedTaskNames(new HashSet<>());

            if (correlationId != null) {
                workflow.setCorrelationId(correlationId);
            }
            if (workflowInput != null) {
                workflow.setInput(workflowInput);
            }
            // Add to decider queue
            queueDAO.push(
                    DECIDER_QUEUE,
                    workflow.getWorkflowId(),
                    workflow.getPriority(),
                    properties.getWorkflowOffsetTimeout().getSeconds());
            executionDAOFacade.updateWorkflow(workflow);
            // update tasks in datastore to update workflow-tasks relationship for archived
            // workflows
            executionDAOFacade.updateTasks(workflow.getTasks());
            // Remove all tasks after the "rerunFromTask"
            List<TaskModel> filteredTasks = new ArrayList<>();
            for (TaskModel task : workflow.getTasks()) {
                if (task.getSeq() > rerunFromTask.getSeq()) {
                    executionDAOFacade.removeTask(task.getTaskId());
                } else {
                    filteredTasks.add(task);
                }
            }
            workflow.setTasks(filteredTasks);
            // reset fields before restarting the task
            rerunFromTask.setScheduledTime(System.currentTimeMillis());
            rerunFromTask.setStartTime(0);
            rerunFromTask.setUpdateTime(0);
            rerunFromTask.setEndTime(0);
            rerunFromTask.clearOutput();
            rerunFromTask.setRetried(false);
            rerunFromTask.setExecuted(false);
            if (rerunFromTask.getTaskType().equalsIgnoreCase(TaskType.TASK_TYPE_SUB_WORKFLOW)) {
                // if task is sub workflow set task as IN_PROGRESS and reset start time
                rerunFromTask.setStatus(IN_PROGRESS);
                rerunFromTask.setStartTime(System.currentTimeMillis());
            } else {
                if (taskInput != null) {
                    rerunFromTask.setInputData(taskInput);
                }
                if (systemTaskRegistry.isSystemTask(rerunFromTask.getTaskType())
                        && !systemTaskRegistry.get(rerunFromTask.getTaskType()).isAsync()) {
                    // Start the synchronous system task directly
                    systemTaskRegistry
                            .get(rerunFromTask.getTaskType())
                            .start(workflow, rerunFromTask, this);
                } else {
                    // Set the task to rerun as SCHEDULED
                    rerunFromTask.setStatus(SCHEDULED);
                    addTaskToQueue(rerunFromTask);
                }
            }
            executionDAOFacade.updateTask(rerunFromTask);
            decide(workflow.getWorkflowId());
            return true;
        }
        return false;
    }
Gets the active domain from the list of domains where the task is to be queued. The domain
list must be ordered. In sequence, check if any worker has polled for last
`activeWorkerLastPollMs`, if so that is the Active domain. When no active domains are found:
<li>If NO_DOMAIN token is provided, return null.
<li>Else, return last domain from list.

@param taskType the taskType of the task for which active domain is to be found
@param domains the array of domains for the task. (Must contain atleast one element).
@return the active domain where the task will be queued
core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutor.java