Child Workflows - TypeScript SDK
How to start a Child Workflow Execution
A Child Workflow Execution is a Workflow Execution that is scheduled from within another Workflow using a Child Workflow API.
When using a Child Workflow API, Child Workflow related Events (StartChildWorkflowExecutionInitiated, ChildWorkflowExecutionStarted, ChildWorkflowExecutionCompleted, etc.) are logged in the Workflow Execution Event History.
The ChildWorkflowExecutionStarted Event must be logged to the Event History before the Parent Workflow completes to ensure the Child Workflow has started.
In TypeScript, awaiting startChild() or executeChild() internally waits for this Event before returning, so the Child Workflow is guaranteed to have started once the call resolves.
If you start a Child Workflow from a non-main context (for example, a Signal or Update handler), make sure the Parent Workflow doesn't complete before that call resolves.
To start a Child Workflow Execution and return a handle to it, use startChild.
import { startChild } from '@temporalio/workflow';
export async function parentWorkflow(names: string[]) {
const childHandle = await startChild(childWorkflow, {
args: [name],
// workflowId, // add business-meaningful workflow id here
// // regular workflow options apply here, with two additions (defaults shown):
// cancellationType: ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED,
// parentClosePolicy: ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE
});
// you can use childHandle to signal or get result here
await childHandle.signal('anySignal');
const result = childHandle.result();
// you can use childHandle to signal, query, cancel, terminate, or get result here
}
To start a Child Workflow Execution and await its completion, use executeChild.
By default, a child is scheduled on the same Task Queue as the parent.
child-workflows/src/workflows.ts
import { executeChild } from '@temporalio/workflow';
export async function parentWorkflow(...names: string[]): Promise<string> {
const responseArray = await Promise.all(
names.map((name) =>
executeChild(childWorkflow, {
args: [name],
// workflowId, // add business-meaningful workflow id here
// // regular workflow options apply here, with two additions (defaults shown):
// cancellationType: ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED,
// parentClosePolicy: ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE
}),
),
);
return responseArray.join('\n');
}
To control any running Workflow from inside a Workflow, use getExternalWorkflowHandle(workflowId).
import { getExternalWorkflowHandle, workflowInfo } from '@temporalio/workflow';
export async function terminateWorkflow() {
const { workflowId } = workflowInfo(); // no await needed
const handle = getExternalWorkflowHandle(workflowId); // sync function, not async
await handle.cancel();
}
If the Child Workflow options aren't explicitly set, they inherit their values from the Parent Workflow options. Two advanced options are unique to Child Workflows:
- cancellationType: Controls when to throw the
CanceledFailureexception when a Child Workflow is canceled. parentClosePolicy: Explained in the next section.
If you need to cancel a Child Workflow Execution, use cancellation scopes. A Child Workflow Execution is automatically cancelled when its containing scope is cancelled.
How to set a Parent Close Policy
A Parent Close Policy determines what happens to a Child Workflow Execution if its Parent changes to a Closed status (Completed, Failed, or Timed Out).
The default Parent Close Policy option is set to terminate the Child Workflow Execution.
To specify how a Child Workflow reacts to a Parent Workflow reaching a Closed state, use the parentClosePolicy option.
child-workflows/src/workflows.ts
import { executeChild } from '@temporalio/workflow';
export async function parentWorkflow(...names: string[]): Promise<string> {
const responseArray = await Promise.all(
names.map((name) =>
executeChild(childWorkflow, {
args: [name],
// workflowId, // add business-meaningful workflow id here
// // regular workflow options apply here, with two additions (defaults shown):
// cancellationType: ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED,
// parentClosePolicy: ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE
}),
),
);
return responseArray.join('\n');
}