################### MainTaskExecutor ################### Purpose ------- The ``MainTaskExecutor`` is the execution engine of the CSP.LMC Long Running Commands framework. Once a task-tree structure has been defined by the TaskComposer, the MainTaskExecutor is responsible for orchestrating the execution of Tasks and LeafTasks, handling concurrency, execution control, and integration with the TANGO LRC mechanism. It does not participate in task composition or status aggregation, which are delegated respectively to the TaskComposer and TaskTracker components. The MainTaskExecutor operates only on task trees successfully produced by the MainTaskComposer. If task composition fails (for example because a task with ``reject_missing=True`` cannot be composed), the command is rejected before reaching the execution phase. Execution model --------------- Execution of a Long Running Command is initiated through the ``submit_main_task`` method. The MainTask is executed in a dedicated thread, while parallel subtasks are dispatched to an internal ``ThreadPoolExecutor``. This separation prevents long-running operations from blocking the calling TANGO device thread. Task execution is performed recursively until all LeafTasks have either completed, failed, or been discarded. Execution flow overview ----------------------- :: Client | | submit_main_task() v MainTaskExecutor | |-- evaluate TaskExecutionType | |-- SEQUENTIAL ---> Task 1 ---> Task 2 ---> Task 3 | |-- PARALLEL ----> Task A ---\ | --> wait for completion |-- INTERNAL ----> CSP method / | |-- DEVICE ------> invoke_lrc() --> TANGO Device | v TaskTracker | |-- aggregate status and result v Client notification The execution strategy applied to each task is determined by its ``TaskExecutionType``. For a detailed description of the supported execution strategies, see :doc:`../tasks/task_execution_type`. Task lifecycle -------------- At a high level, the lifecycle of a task execution is the following: 1. The MainTask is submitted to the executor. 2. The execution type of the task is evaluated. 3. Subtasks are submitted according to the execution strategy. 4. LeafTasks perform the actual command execution. 5. Completion is signalled through the associated TaskTracker. 6. Status and results are propagated via callbacks. Timeout, abort and skip handling -------------------------------- The MainTaskExecutor supports execution control mechanisms to ensure robust command handling. A global timeout can be associated with the execution of a MainTask. When the timeout expires, pending or not-yet-started LeafTasks are discarded and reported as rejected. An explicit abort request can be issued to interrupt command execution. In this case, running tasks are notified and pending tasks are aborted. For sequential execution, failures may trigger the skipping of subsequent subtasks, depending on the task configuration. Integration with TANGO LRC -------------------------- For DEVICE LeafTasks, the MainTaskExecutor relies on the ``invoke_lrc`` API provided by ``ska-tango-base``. The executor subscribes to LRC events emitted by the target device and forwards execution updates to the associated TaskTracker, which is responsible for tracking progress and completion Status (see :doc:`../task_tracker/index`). Threading and concurrency model -------------------------------- The executor uses a hybrid threading model: * One dedicated thread per MainTask. * A configurable ``ThreadPoolExecutor`` for parallel execution. This design enables controlled concurrency while preserving a clear execution context for each command.