-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Problem
The WhenAllTask constructor resets _completedTasks to 0 after calling super(tasks). The CompositeTask base constructor processes already-complete children via onChildCompleted(), correctly incrementing _completedTasks. The subsequent reset in WhenAllTask discards this count.
File: packages/durabletask-js/src/task/when-all-task.ts, lines 14-15
Root Cause
The initialization of _completedTasks and _failedTasks in WhenAllTask's constructor is redundant — CompositeTask already initializes both fields to 0 before iterating children. The re-initialization in WhenAllTask runs after the base class loop, wiping out any increments from pre-completed children.
Impact
When WhenAllTask is constructed with a mix of already-complete and pending tasks:
CompositeTaskcorrectly counts the already-complete children (e.g.,_completedTasks = K)WhenAllTaskresets_completedTasks = 0- When the remaining
N - Ktasks complete,_completedTasksreachesN - Kinstead ofN - The completion check
_completedTasks == _tasks.length(N - K == N) is never true - The
WhenAllTasknever completes, causing the orchestration to hang indefinitely
This can occur whenever an orchestrator reuses a previously completed task reference in a whenAll call.
Proposed Fix
Remove the redundant this._completedTasks = 0 and this._failedTasks = 0 lines from the WhenAllTask constructor. The base class CompositeTask already handles initialization before processing pre-completed children.
Note: _failedTasks is also dead code — it is declared and initialized but never incremented anywhere in the codebase.