Child Workflow Events logged to Workflow Execution Event History
When using the Child Workflow API in Rust, Child Workflow related Events are logged to the Workflow Execution Event History: StartChildWorkflowExecutionInitiated, ChildWorkflowExecutionStarted, and ChildWorkflowExecutionCompleted. The ChildWorkflowExecutionStarted Event must be logged to the Event History before the Parent Workflow completes to ensure the Child Workflow has started.
ChildWorkflowOptions struct for customizing Child Workflow behavior
Use ChildWorkflowOptions to customize Child Workflow behavior in Rust. Available at https://docs.rs/temporalio-sdk/0.2.0/temporalio_sdk/struct.ChildWorkflowOptions.html. Commonly used fields include workflow_id and parent_close_policy.
Execute multiple Child Workflows in parallel in Rust
Start multiple Child Workflows by calling ctx.child_workflow() multiple times without awaiting intermediate results. Both child workflows run in parallel and the parent can wait for all of them to complete by calling result() on each child workflow handle sequentially.
Parent Close Policy options in Rust
Three Parent Close Policy options are available: Terminate (default) - Child Workflow is terminated immediately when parent closes; Abandon - Child Workflow continues running even if parent closes; RequestCancel - Child Workflow receives a cancellation request when parent closes.
Parent Close Policy default is Terminate
The default Parent Close Policy in Rust is set to terminate the Child Workflow Execution when the parent closes.
Example: Set Parent Close Policy to Abandon in Rust
```rust
use temporalio_common::protos::temporal::api::{enums::v1::ParentClosePolicy};
let es_greeting_child = ctx.child_workflow(
ComposeEsGreetingWorkflow::run,
name.clone(),
ChildWorkflowOptions {
workflow_id: format!("greeting-child-es"),
parent_close_policy: ParentClosePolicy::Abandon,
..Default::default()
},
).await?;
```
This example shows how to set the parent_close_policy field in ChildWorkflowOptions to allow the child workflow to continue running after the parent closes.
Example: Start single Child Workflow in Rust
```rust
let started = ctx.child_workflow(
ComposeGreetingWorkflow::run,
name.clone(),
ChildWorkflowOptions {
workflow_id: format!("greeting-child-en"),
..Default::default()
},
).await?;
let result = started.result().await;
```
This example shows starting a single child workflow, awaiting it to start, then getting its result.
Example: Multiple parallel Child Workflows in Rust
```rust
let en_greeting_child = ctx.child_workflow(
ComposeEnGreetingWorkflow::run,
name.clone(),
ChildWorkflowOptions {
workflow_id: format!("greeting-child-en"),
..Default::default()
},
).await?;
let es_greeting_child = ctx.child_workflow(
ComposeEsGreetingWorkflow::run,
name.clone(),
ChildWorkflowOptions {
workflow_id: format!("greeting-child-es"),
..Default::default()
},
).await?;
let en_result = en_greeting_child.result().await;
let es_result = es_greeting_child.result().await;
```
This example shows starting two child workflows in parallel and then waiting for both results.
Go SDK: Set child workflow priority
In Go, set child workflow priority using the Priority field in ChildWorkflowOptions:
```go
cwo := workflow.ChildWorkflowOptions{
WorkflowID: "child-workflow-id",
TaskQueue: "child-task-queue",
Priority: temporal.Priority{
PriorityKey: 1,
FairnessKey: "a-key",
FairnessWeight: 3.14,
},
}
ctx := workflow.WithChildOptions(ctx, cwo)
err := workflow.ExecuteChildWorkflow(ctx, MyChildWorkflow).Get(ctx, nil)
```
How child workflows and activities inherit priority from parent workflow
Activities and Child Workflows inherit their calling Workflow's priority unless they explicitly specify their own priority. Each field (priority_key, fairness_key, fairness_weight) is resolved independently.
Ruby SDK: Set child workflow fairness
In Ruby, set child workflow priority and fairness using the priority parameter with Temporalio::Priority.new():
```ruby
client.start_child_workflow(
MyChildWorkflow, "input-arg",
id: "my-child-workflow-id",
task_queue: "my-task-queue",
priority: Temporalio::Priority.new(
priority_key: 3,
fairness_key: "a-key",
fairness_weight: 3.14
)
)
```
Java SDK: Set child workflow priority
In Java, set child workflow priority using ChildWorkflowOptions.setPriority():
```java
ChildWorkflowOptions childOptions = ChildWorkflowOptions.newBuilder()
.setTaskQueue("child-task-queue")
.setWorkflowId("child-workflow-id")
.setPriority(Priority.newBuilder().setPriorityKey(1).setFairnessKey("a-key").setFairnessWeight(3.14).build())
.build();
MyChildWorkflow child = Workflow.newChildWorkflowStub(MyChildWorkflow.class, childOptions);
child.run();
```
Python SDK: Set child workflow priority
In Python, set child workflow priority using the priority parameter in execute_child_workflow():
```python
await workflow.execute_child_workflow(
MyChildWorkflow.run,
args="hello child",
priority=Priority(priority_key=3, fairness_key="a-key", fairness_weight=3.14),
)
```
TypeScript SDK: Set child workflow priority
In TypeScript, set child workflow priority using the priority object in startChildWorkflow options:
```ts
const handle = await startChildWorkflow(workflows.priorityWorkflow, {
args: [false, 1],
priority: { priorityKey: 3, fairnessKey: 'a-key', fairnessWeight: 3.14 },
});
```
Child Workflow Execution definition
A Child Workflow Execution is a Workflow Execution that is scheduled from within another Workflow using a Child Workflow API.
Child Workflow Events logged to history
When using a Child Workflow API, Child Workflow related Events (StartChildWorkflowExecutionInitiated, ChildWorkflowExecutionStarted, ChildWorkflowExecutionCompleted) are logged in the Workflow Execution Event History.
ChildWorkflowExecutionStarted Event requirement before parent completion
The ChildWorkflowExecutionStarted Event must be logged to the Event History before the Parent Workflow completes to ensure the Child Workflow has started.
startChild() and executeChild() wait for ChildWorkflowExecutionStarted Event
In TypeScript, awaiting startChild() or executeChild() internally waits for the ChildWorkflowExecutionStarted Event before returning, so the Child Workflow is guaranteed to have started once the call resolves.
Child Workflow from Signal or Update handler completion guarantee
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.
startChild() TypeScript API
Use startChild() from @temporalio/workflow to start a Child Workflow Execution and return a handle to it. The function signature is startChild(childWorkflow, options) where options can include args, workflowId, cancellationType, and parentClosePolicy.
executeChild() TypeScript API
Use executeChild() from @temporalio/workflow to start a Child Workflow Execution and await its completion.
Child Workflow default task queue
By default, a child is scheduled on the same Task Queue as the parent.
getExternalWorkflowHandle() for external workflow control
Use getExternalWorkflowHandle(workflowId) to control any running Workflow from inside a Workflow. This is a synchronous function, not async.
Child Workflow options inheritance
If the Child Workflow options aren't explicitly set, they inherit their values from the Parent Workflow options.
cancellationType option for Child Workflows
The cancellationType option controls when to throw the CanceledFailure exception when a Child Workflow is canceled.
Parent Close Policy definition
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).
Default Parent Close Policy
The default Parent Close Policy option is set to terminate the Child Workflow Execution.
parentClosePolicy option in TypeScript
Use the parentClosePolicy option to specify how a Child Workflow reacts to a Parent Workflow reaching a Closed state.
Child Workflow cancellation with scopes
To cancel a Child Workflow Execution, use cancellation scopes. A Child Workflow Execution is automatically cancelled when its containing scope is cancelled.
startChild() TypeScript example
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
}
executeChild() TypeScript example
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');
}
getExternalWorkflowHandle() TypeScript example
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();
}