Best way to create an async child workflow

What’s the best way to start a child workflow async?

The important thing is to start the workflow, then the child workflow does not need to be associated with the parent workflow any more.

Currently, it is not straightforward. We have plans to improve the experience (relevant issue), but in the meantime, the following should be done.

Java SDK

  1. Set ChildWorkflowOptions.ParentClosePolicy to ABANDON when creating a child workflow stub.
  2. Start child workflow asynchronously using Async.function or Async.procedure.
  3. Call Workflow.getWorkflowExecution(…) on the child stub
  4. Wait for the Promise returned by getWorkflowExecution to complete. This indicates that the child successfully started (or start failed).
  5. Complete parent workflow.

Steps 3 and 4 are needed to ensure that child workflow starts before the parent closes. If the parent initiates child workflow and immediately completes the child would never start. Here is the code that demonstrates the steps:

   public void parentWorklfow() {
       ChildWorkflowOptions options =
          ChildWorkflowOptions.newBuilder()
              .setCancellationType(ChildWorkflowCancellationType.ABANDON)
              .build();
       MyChildWorkflow child = Workflow.newChildWorkflowStub(MyChildWorkflow.class, options);
       Promise<WorkflowExecution> childExecution = Workflow.getWorkflowExecution(child);
       // Wait for child to start
       childExecution.get()
  }

Go SDK

  1. Set ChildWorkflowOptions.ParentClosePolicy to ABANDON when creating a child workflow stub.
  2. Start child workflow using ExecuteChildWorkflow
  3. Call GetChildWorkflowExecution on the ChildWorkflowFuture returned by the ExecuteChildWorkflow
  4. Wait on the WorkflowExecution Future. This indicates that the child successfully started (or start failed).
  5. Complete parent workflow

Steps 3 and 4 are needed to ensure that child workflow starts before the parent closes. If the parent initiates child workflow and immediately completes the child would never start. Here is the code that demonstrates the steps (error handling omitted for brevity):

func ParentWorkflow(ctx workflow.Context) error {
    childWorkflow := workflow.ExecuteChildWorkflow(ctx, MyChildWorkflow)
    // Wait for child to start
    _ = childWorkflow.GetChildWorkflowExecution().Get(ctx, nil)
    return nil
}
2 Likes

I am using an activity to do something like that. the activity just submits a workflow and returns! of course in my usecase, i really dont care about the outcome of the child workflow, hence it kind of works for me… but don know the consequences . @maxim any suggestions?

@madhu It also works, you should be careful about assigning ID to the child when starting it this way to avoid duplicated workflows if start times out for some reason.

Hi Maxim, is there a reason the cancellation type doesn’t need to be set to ABANDON when executing child workflows using the Go SDK?

Good catch. I actually specified incorrect option in both Java and Go cases. It should read:

  1. Set ChildWorkflowOptions.ParentClosePolicy to ABANDON when creating a child workflow stub.

I updated the original post.

Thanks for the quick response. I’m having some trouble determining the type of ChildWorkflowOptions.ParentClosePolicy. The source code points to an enum in the generated protobuf api. but I can’t seem to find the values anywhere.

Here is protobuf definition.

Can parent workflows start child workflows with the exact same ID ?

ie can a parent with ID ABC start a child workflow with id ABC.

I have a use case the last action of a workflow should be to create a child workflow, fire and forget style, like explained above. The child needs to get the same ID as the parent.

It is not ever allowed to have two workflows with the same ID open at the same time. So the parent cannot start a child with its own id.

But the parent can call continue as new with any other type. Continue as new closes a workflow run and creates a new one atomically. So it achieves your goal with even simpler code.

1 Like

ah great ! Excellent this was exactly what I was looking for !