How to spawn a Child Workflow Execution in Java
The first call to the Child Workflow stub must always be its Workflow method (method annotated with @WorkflowMethod
).
Similar to Activities, invoking Child Workflow methods can be made synchronous or asynchronous by using Async#function
or Async#procedure
.
The synchronous call blocks until a Child Workflow method completes.
The asynchronous call returns a Promise
which can be used to wait for the completion of the Child Workflow method, as in the following example:
GreetingChild child = Workflow.newChildWorkflowStub(GreetingChild.class);
Promise<String> greeting = Async.function(child::composeGreeting, "Hello", name);
// ...
greeting.get()
To execute an untyped Child Workflow asynchronously, call executeAsync
on the ChildWorkflowStub
, as shown in the following example.
//...
ChildWorkflowStub childUntyped =
Workflow.newUntypedChildWorkflowStub(
"GreetingChild", // your workflow type
ChildWorkflowOptions.newBuilder().setWorkflowId("childWorkflow").build());
Promise<String> greeting =
childUntyped.executeAsync(String.class, String.class, "Hello", name);
String result = greeting.get();
//...
The following examples show how to spawn a Child Workflow:
Spawn a Child Workflow from a Workflow:
// Child Workflow interface
@WorkflowInterface
public interface GreetingChild {
@WorkflowMethod
String composeGreeting(String greeting, String name);
}
// Child Workflow implementation not shown
// Parent Workflow implementation
public class GreetingWorkflowImpl implements GreetingWorkflow {
@Override
public String getGreeting(String name) {
GreetingChild child = Workflow.newChildWorkflowStub(GreetingChild.class);
// This is a blocking call that returns only after child has completed.
return child.composeGreeting("Hello", name );
}
}Spawn two Child Workflows (with the same type) in parallel:
// Parent Workflow implementation
public class GreetingWorkflowImpl implements GreetingWorkflow {
@Override
public String getGreeting(String name) {
// Workflows are stateful, so a new stub must be created for each new child.
GreetingChild child1 = Workflow.newChildWorkflowStub(GreetingChild.class);
Promise<String> greeting1 = Async.function(child1::composeGreeting, "Hello", name);
// Both children will run concurrently.
GreetingChild child2 = Workflow.newChildWorkflowStub(GreetingChild.class);
Promise<String> greeting2 = Async.function(child2::composeGreeting, "Bye", name);
// Do something else here.
...
return "First: " + greeting1.get() + ", second: " + greeting2.get();
}
}Send a Signal to a Child Workflow from the parent:
// Child Workflow interface
@WorkflowInterface
public interface GreetingChild {
@WorkflowMethod
String composeGreeting(String greeting, String name);
@SignalMethod
void updateName(String name);
}
// Parent Workflow implementation
public class GreetingWorkflowImpl implements GreetingWorkflow {
@Override
public String getGreeting(String name) {
GreetingChild child = Workflow.newChildWorkflowStub(GreetingChild.class);
Promise<String> greeting = Async.function(child::composeGreeting, "Hello", name);
child.updateName("Temporal");
return greeting.get();
}
}Sending a Query to Child Workflows from within the parent Workflow code is not supported. However, you can send a Query to Child Workflows from Activities using
WorkflowClient
.
Related reads: