1616from pytask import PTask
1717from pytask import PythonNode
1818from pytask import Session
19+ from pytask import TaskExecutionStatus
1920from pytask import console
2021from pytask import get_marks
2122from pytask import hookimpl
@@ -52,6 +53,7 @@ def pytask_execute_build(session: Session) -> bool | None: # noqa: C901, PLR091
5253 __tracebackhide__ = True
5354 reports = session .execution_reports
5455 running_tasks : dict [str , Future [Any ]] = {}
56+ any_coiled_task = any (is_coiled_function (task ) for task in session .tasks )
5557
5658 # The executor can only be created after the collection to give users the
5759 # possibility to inject their own executors.
@@ -66,12 +68,31 @@ def pytask_execute_build(session: Session) -> bool | None: # noqa: C901, PLR091
6668 while session .scheduler .is_active ():
6769 try :
6870 newly_collected_reports = []
69- ready_tasks = list (session .scheduler .get_ready (10_000 ))
71+
72+ # If there is any coiled function, the user probably wants to exploit
73+ # adaptive scaling. Thus, we need to submit all ready tasks.
74+ # Unfortunately, all submitted tasks are shown as running although some
75+ # are pending.
76+ #
77+ # Without coiled functions, we submit as many tasks as there are
78+ # available workers since we cannot reliably detect a pending status.
79+ #
80+ # See #98 for more information.
81+ if any_coiled_task :
82+ n_new_tasks = 10_000
83+ else :
84+ n_new_tasks = session .config ["n_workers" ] - len (running_tasks )
85+
86+ ready_tasks = (
87+ list (session .scheduler .get_ready (n_new_tasks ))
88+ if n_new_tasks >= 1
89+ else []
90+ )
7091
7192 for task_name in ready_tasks :
7293 task = session .dag .nodes [task_name ]["task" ]
7394 session .hook .pytask_execute_task_log_start (
74- session = session , task = task
95+ session = session , task = task , status = TaskExecutionStatus . RUNNING
7596 )
7697 try :
7798 session .hook .pytask_execute_task_setup (
0 commit comments