class_docstr: Execute tasks in the order of the dependencies in the plan, one by one.
class_docstr_tok: ["Execute","tasks","in","the","order","of","the","dependencies","in","the","plan",",","one","by","one","."]
docstr: Traverse the execution plan via depth first search.
  
  Executing the parents tasks first, then the current task.
docstr_tok: ["Traverse","the","execution","plan","via","depth","first","search",".","Executing","the","parents","tasks","first",",","then","the","current","task","."]
code: def _execute_dfs(
      self, current_task: ExecutionPlanTask, results: ExecutionResults
  ) -> None:
      """Traverse the execution plan via depth first search.
  
      Executing the parents tasks first, then the current task.
      """
      for parent_node in current_task.parent_nodes:
          self._execute_dfs(parent_node, results)
          if results.contains_task_errors:
              return
  
      result = None
      logger.info(f"Started task ID: {current_task.node_id}")
      try:
          result = current_task.execute()
          results.add_result(current_task.task_id, result)
      finally:
          if result:
              runtime = f"{result.end_time - result.start_time:.2f}s"
              if result.errors:
                  logger.info(
                      f"Finished task ID: {current_task.node_id} with errors: {result.errors} in {runtime}"
                  )
              else:
                  logger.info(
                      f"Finished task ID: {current_task.node_id} successfully in {runtime}"
                  )
          else:
              logger.info(
                  f"Task ID: {current_task.node_id} exited unexpectedly"
              )
  
file_path: metricflow/metricflow/execution/executor.py
imports: from __future__ import annotations
  import logging
  from abc import ABC, abstractmethod
  from collections import OrderedDict
  from typing import Dict
  from metricflow.dag.mf_dag import NodeId
  from metricflow.execution.execution_plan import ExecutionPlan, ExecutionPlanTask, TaskExecutionResult
label_desc: Use image node_id 1 for calling the SequentialPlanExecutor obj's underlying member method code with example usage: obj._execute_dfs(current_task, results) without return types