Parent–child Flows
Start a child Flow and wait for its completion from the parent.
Problem and approach
Here we demonstrate how to start a child Flow and wait for its completion.
The pattern is particular useful when you need to fan out the Flow executions for parallelism, or for any other reasons that a parent Flow need to wait for a child to complete.
There are two different ways in Dex.
Option 1: Let child Flow send back signal on completion
This is the option that we implemented in scalable parallel design pattern. It's the most efficient but also a bit complex.
- Parent should use
ignoreAlreadyStarted=truewithrequestIdwhen starting childFlow - Parent must use dynamic channel name to wait for each child Flow to complete.
Additionally, each child can only notify one single parent on completion. If there could be multiple parents, this approach will not work. This means that multiple parent executions can be mapped to multiple(MtoM) child executions. For real production example, a billing refund request(as a parent Flow) may contain multiple invoices, each invoice will be a child Flow, but different billing refund requests may contain some overlapping invoices, and each refund parent Flow will have to wait for its associated children to complete.
Option2: Let parent Flow wait for child Flow completion via client API
In the above MtoM case, there is an even simpler way: from an async parent Step, await client.waitForFlow(childId, timeoutMs) (TypeScript) or the equivalent SDK long-poll wait API.
Catch long-poll timeouts when the child may take longer than the poll window, then loop with a durable timer. See TypeScript SDK notes.
And potentially, use a timer condition to wait with some interval if it is expected to take more than the poll timeout.
This approach may look simpler for some people, without the overhead of understanding ignoreAlreadyStarted + requestId and "dynamic channel".
So we will implement it here.
Compared to Option1, this option is less efficient in terms of Temporal actions usage -- it will consume Temporal actions for every iteration of AwaitChildFlowCompletionStep until the child completed, if the child Flow takes very long time (like days), it's not recommended to use this option to wait for child Flow. You should use option1, although a little more code to write.
But if child Flow can normally complete within minutes, this is probably the easiest way to deal with child Flow, and it's more flexible to support MtoM relationship of parent&child.
Code examples
Full runnable samples live under examples/{go,java,python,typescript} (HTTP prefix /design-pattern/... where applicable).
# See examples/python/dex_examples/patterns/workflow/parentchild/