Skip to main content

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: