|
15 | 15 | T = TypeVar("T") |
16 | 16 |
|
17 | 17 |
|
| 18 | +def _tasks_are_independent(tasks: list[Task[Any]]) -> bool: |
| 19 | + """Check if tasks have no dependencies between each other.""" |
| 20 | + for i, task1 in enumerate(tasks): |
| 21 | + for j, task2 in enumerate(tasks): |
| 22 | + if i != j: |
| 23 | + # Check if task1 depends on task2 or vice versa |
| 24 | + if task2 in task1.depends_on or task1 in task2.depends_on: |
| 25 | + return False |
| 26 | + # Check if they share subtasks or parent relationships |
| 27 | + if task1.parent == task2 or task2.parent == task1: |
| 28 | + return False |
| 29 | + if task1 in task2.subtasks or task2 in task1.subtasks: |
| 30 | + return False |
| 31 | + return True |
| 32 | + |
| 33 | + |
18 | 34 | async def run_tasks_async( |
19 | 35 | tasks: list[Task[Any]], |
20 | 36 | thread: Thread | str | None = None, |
21 | 37 | raise_on_failure: bool = True, |
22 | 38 | handlers: list[Handler | AsyncHandler] | None = None, |
23 | 39 | ) -> list[Task[Any]] | AsyncGenerator[Event, None]: |
24 | | - orchestrator = Orchestrator( |
25 | | - tasks=tasks, |
26 | | - thread=thread, |
27 | | - handlers=handlers, |
28 | | - ) |
29 | | - await orchestrator.run(raise_on_failure=raise_on_failure) |
30 | | - return tasks |
| 40 | + """Run tasks either concurrently (if independent) or sequentially via orchestrator.""" |
| 41 | + # If we have multiple independent tasks, run them concurrently |
| 42 | + if len(tasks) > 1 and _tasks_are_independent(tasks): |
| 43 | + # Run independent tasks concurrently using asyncio.gather |
| 44 | + await asyncio.gather(*[task.run_async() for task in tasks]) |
| 45 | + return tasks |
| 46 | + else: |
| 47 | + # Use orchestrator for dependent tasks or single tasks |
| 48 | + orchestrator = Orchestrator( |
| 49 | + tasks=tasks, |
| 50 | + thread=thread, |
| 51 | + handlers=handlers, |
| 52 | + ) |
| 53 | + await orchestrator.run(raise_on_failure=raise_on_failure) |
| 54 | + return tasks |
31 | 55 |
|
32 | 56 |
|
33 | 57 | async def run_tasks_stream( |
@@ -79,6 +103,7 @@ def run_tasks( |
79 | 103 | raise_on_failure: bool = True, |
80 | 104 | handlers: list[Handler | AsyncHandler] | None = None, |
81 | 105 | ) -> list[Task[Any]]: |
| 106 | + """Run tasks either concurrently (if independent) or sequentially.""" |
82 | 107 | return marvin.utilities.asyncio.run_sync( |
83 | 108 | run_tasks_async( |
84 | 109 | tasks=tasks, |
|
0 commit comments