What is the best way to start a child workflow (with a specific workflowID) if it doesn't already exist as one atomic operation?

I’m trying to create a setup where several workflow instances rely on the results of the same child workflow (with a specific workflowID). Currently, if all the parent workflows attempt to execute the child workflow simultaneously only one of them is able to read the results and the rest get a ChildWorkflowExecutionError that says “workflow already started”. Is there any way to replicate what workflow.ExecuteWorkflow does where if the workflow is already running or exists, it just returns the result of the existing workflow?

Unfortunately, it is not yet supported directly. Here is the issue to get such a feature added.

The workaround is on “workflow already started” to execute an activity that the result of a workflow using WorkflowClient.

Appreciate the prompt response as always. I was thinking about falling back to the solution you suggested, but I wasn’t sure if it would violate correctness. Great to know that it is indeed a valid workaround. Thanks!

Calling WorkflowClient from workflow directly will violate correctness. Calling it as any other API from an activity is always OK.

1 Like

Is this solution robust to race conditions with the workflow expiry? The proposed solution sketched out seems to be

  1. Try to execute a child workflow
  2. If executeChildWorkflow() returns an a WorkflowExecutionAlreadyStarted error, then
  3. Execute an activity to get the result of the already-existing workflow.

From my understanding, if any workflow with the same ID is in the history, then executeChildWorkflow will return an error, even if the workflow is already completed (unless you allow duplicates, but we aren’t allowing them in this use case). If the workflow expires between between step 2 and 3, it seems like step 3 would fail. Is that right?

Yes, it will fail, and you’ll have to retry the whole sequence from 1.

1 Like