Replies: 1 comment
-
Implemented in #289 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Problem
Currently, the Hatchet Python, TypeScript, and Go SDKs support defining workflows as a Directed Acyclic Graph (DAG), where steps are declared upfront and dependencies between steps are specified. However, there are scenarios where the number of child workflows needed is not known until runtime, and the results of these child workflows need to be joined and processed by a parent workflow. The current SDK lacks the capability to dynamically spawn child workflows based on runtime conditions and join their results before continuing execution of future downstream steps.
Example Use Cases
Proposed Solution
Extend the Hatchet Python, TypeScript, and Go SDKs to support procedural child workflow spawning (fanout) and joining of the results of these child workflows. This will involve introducing new SDK methods and modifying the workflow execution engine to handle dynamic child workflow creation and result joining.
By exposing a
spawn_workflow
method on the step context, we're able to reference the child from the parent workflow run. In other words, we'll be able to trace the workflow state for the entire parent-and-child invocation.Proposed SDK Design
Python
Signatures:
Example Usage:
TypeScript
Signatures:
Example Usage:
Workflow Execution Engine Modifications
context.spawn_workflow()
method.Risks/Unknowns
maxRuns
) to 1 to ensure sequential execution.Notes on Durability and Idempotency
To ensure durability and idempotency in child workflow spawning, we propose two strategies:
Input Hashing:
spawn_workflow
is called with specific input data, the input data is hashed to generate a unique identifier.workflowRunId
) and the input hash is used to check for collisions.workflowRunId
and input hash already exists, instead of spawning a new child workflow, the method subscribes to the existing child workflow and returns its promise.Key Argument:
spawn_workflow
method accepts an optionalkey
argument that allows the user to provide a custom identifier for the child workflow.key
argument is provided, it overrides the default behavior of input hashing.workflowRunId
) and the providedkey
is used to check for collisions.workflowRunId
andkey
already exists, the method subscribes to the existing child workflow and returns its promise.After all child workflows are dispatched, the parent workflow should use
context.join
(which callsPromise.all
orasyncio.gather
under the hood) to wait for the completion of all child workflows and retrieve their results. This ensures that the parent workflow progresses only when all child workflows have finished executing. If the parent workflow step fails and retries, the join will resume from the last spawned state.UI Considerations
Representing a large number of spawned child workflows in the parent workflow's DAG view can be challenging.
Instead of cluttering the DAG with numerous child workflow nodes, the
spawn_workflows
step can render a table or list of “spawned” or “linked” child workflow runs. This table provides an overview of the spawned child workflows' status, progress, and links to individual details. Clicking a run can open a modal or navigate to that specific invocation.Users can click on a specific child workflow in the table to navigate to its detailed view, displaying the child workflow's own DAG, steps, and execution details.
Beta Was this translation helpful? Give feedback.
All reactions