Executes a workflow by managing the execution of tasks based on their dependencies and the provided service registry.
This function orchestrates the execution of tasks in a workflow, ensuring that each task waits for its dependencies to complete before starting. It uses multithreading to execute tasks in parallel while respecting dependencies and resource constraints. Each task interacts with the provided results container and may trigger updates to it.
This function handles a workflow where tasks are represented as a list of dictionaries. Each task is executed in parallel using multithreading, respecting dependencies between tasks. Tasks communicate their completion status via channels, and their execution may update the results container.
# Arguments
- `tasks::Dict`: A dictionary where keys are task names and values are dictionaries containing task details. Task details include:
- `dependencies`: A list of other task names that must complete before this task can run.
- Other relevant task-specific information needed for execution.
- `results_container::Dict`: A dictionary representing the results container, used by tasks to store or retrieve results.
- `system::OrchestratorRegistry.ServiceRegistry`: The service registry used to manage services required by tasks during execution.
- tasks_list::Vector{Dict}: A list of task dictionaries. Each dictionary represents a task and includes the following keys:
- id (String): The unique identifier for the task.
- dependencies (Vector{String}): A list of task IDs that must complete before this task can run.
- Other relevant task-specific information (e.g., service, function, arguments).
- results_container::Dict: A dictionary representing the results container, used by tasks to store or retrieve results.
- system::OrchestratorRegistry.ServiceRegistry: The service registry used to manage services required by tasks during execution.
# Returns
- `Ref{Bool}`: A reference to a boolean flag indicating whether the results container requires saving due to updates during task execution.
- None
# Behavior
- Initializes channels for each task to signal dependency completion.
- Spawns a thread for each task, ensuring it waits for its dependencies to signal completion.
- Uses the `system` parameter to provide access to necessary services during task execution.
- Updates the `results_container` and tracks whether it requires saving using an atomic boolean flag.
1. Converts the tasks_list into a dictionary (Dict{String, Dict}) where the task id is the key for efficient access.
2. Initializes channels for each task to signal dependency completion.
3. Spawns a thread for each task:
- Waits for dependencies to complete before execution.
- Executes the task, updating the results_container and other relevant data structures.
4. Ensures all tasks are completed before the function exits.
# Example
To execute a workflow, define the tasks, results container, and service registry:
Parses a workflow configuration file in TOML format to extract the tasks defined in the workflow.
Parses a workflow configuration file in TOML format into a flat list of dictionaries. Each task is represented as a dictionary, including an `id` key for its name.
# Arguments
- `filePath::String`: The path to the workflow configuration file in TOML format.
- filePath::String: The path to the TOML file containing the workflow configuration.
# Returns
- `Dict{String, Any}`: A dictionary containing the tasks defined in the workflow file. Each key represents a task name, and the value is another dictionary containing the task's properties and configurations.
- Vector{Dict}: A list of task dictionaries. Each dictionary represents a task and includes:
- id (String): The unique identifier for the task (extracted from the task name).
- Other key-value pairs corresponding to task-specific details from the TOML file.
# Behavior
- Reads the specified TOML file and checks for a `tasks` section.
- Returns the `tasks` dictionary if it exists.
- Throws an error if the `tasks` section is missing.
# Raises
- `Error`: If the `tasks` section is not found in the TOML file.
1. Reads and parses the specified TOML file.
2. Ensures the file contains a "tasks" section.
3. Converts each task entry into a dictionary, adding an `id` field corresponding to the task name.
This function reads the specified TOML file, ensuring the presence of a `tasks` section and parsing it into a dictionary for further processing in the workflow management system.
# Usage:
tasks = parseWorkflow("path/to/workflow.toml")
for task in tasks
println("TaskID:", task["id"])
println("Service:", task["service"])
end
``
"""
function parseWorkflow(filePath::String)
# Parse the TOML file
data=TOML.parsefile(filePath)
ifhaskey(data,"tasks")
returndata["tasks"]# Return the tasks dictionary
else
# Ensure the "tasks" section exists
if!haskey(data,"tasks")
error("Invalid workflow file: 'tasks' section not found.")
end
# Flatten tasks into a list of dictionaries
tasks=[]
for(task_name,task_details)indata["tasks"]
iftask_detailsisaDict
# Add the task name as the "id" and flatten into a single dictionary
task_details["id"]=task_name
push!(tasks,task_details)
else
error("Invalid task structure for task '$task_name': Expected a dictionary.")