Workflows with the same workflow ID but different run IDs

Is it possible to create many instances of the same workflow but in such a way that each workflow has the same workflow ID but a different run ID?

A silly example here. Let’s say that I have different types of vehicles that I want to model as Temporal workflows. I create a Car workflow with some specific logic (start up, drive, park, etc.). I want each Car workflow to have the same workflow ID (car-workflow) but for each different car that I’m modeling to have a different run ID. That way, when I want to interact with a specific Car workflow (query it, signal it, terminate it, etc.) I don’t need two separate opaque identifiers to discover it. I just need car-workflow and the run ID.

I should make it clear that these workflows have no ContinueAsError logic or anything like that.

I’ve tried to create this kind of workflow but every time I try to execute it from my starter logic, it doesn’t create a new workflow. Instead, it returns the workflow ID and run ID of a workflow that already exists.

It is possible, of course, that this goes against Temporal’s whole worldview and that it’s a bad idea. Please tell me if so :smile:

Metadata:

  • I’ve been using the Go SDK

It indeed goes against Temporal’s core design idea that only one workflow per WorkflowID can be open at a time.

I don’t understand your use case. Why do you want to have a single ID for all your car workflows? What’s wrong with having a CarID as a WorkflowID? Are any operations/patterns that are not possible with the supported approach?

I don’t need two separate opaque identifiers to discover it. I just need car-workflow and the run ID.

You don’t need two separate opaque identifiers. You can assign your own business-level CarID as WorkflowID And RunID is optional for all the operations. So you can query/signal/terminate by WorkflowID only.

@maxim Okay, I think there’s something I’m missing here, because what you’re describing is what I’ve been attempting. In my start options I use constants:

opts := client.StartWorkflowOptions{
		ID: "car-workflow",
		TaskQueue: "cars",
}

But if I run ExecuteWorkflow with those options, it only creates a new workflow the first time:

car := Car{
        Make: "mercedes",
}

w, err := cl.ExecuteWorkflow(ctx, opts, CarWorkflow, car)
if err != nil {
        log.Fatalln(err)
}

log.Println("started workflow", "WorkflowID", w.GetID(), "RunID", w.GetRunID())

So if I run this once with a fresh Temporal server, I get car-workflow and a run ID back. But if I run it again with a different input value, I get the same run ID and the UI confirms that there’s only one instance of the car-workflow workflow running.

No, I’m proposing to use the business CarID as the workflow ID. You are using fixed string “car-workflow” as the workflow id. And Temporal doesn’t allow more than one workflow with given WorkflowID at the time by design.

How do you identify different cars in your application?

@maxim Ah okay, I’ve got things working exactly the way that I want now. Like you said, I’m supplying my own domain-specific ID as the workflow ID upon initial execution and then supplying an empty string as the run ID when interacting and it’s working great. Thanks a lot!

I think the conceptual blocker for me was not realizing that the run ID is optional. Might be worth emphasizing that in the docs or perhaps adding a section on workflow naming and discoverability patterns.

1 Like