Temporal: how do I check if a workflow has already started

I have the following scenario:

  1. In process1: a workflow with id ‘WorkflowId’ has been started or not
  2. In process2: I want to send a signal to the workflow with ‘WorkflowId’

I know how to send a signal to a running workflow. However, if the workflow has never been started, of course I get an exception when trying to query it.

    @Test @Description("When workflow2 never started, querying it throws an exception")
    void addValueToAnotherWorkflow_workflowNeverStarted() {
        int id = 1;
        var workflow2Id = "Workflow2-Id1"
        var workflow2 = workflowClient.newWorkflowStub(TestWorkflow2.class, getWorkflowOptions(workflow2Id));

        assertThrows(Exception.class, workflow2::acceptsValue);
    }

My question: is there a way to find out programmatically if the workflow has been started already?

Hi @Mathijstb

You can use DescribeWorkflowExecution to verify whether a workflow is running or not.

However, if the workflow has never been started, of course I get an exception.

You can use signalWithStart, which will start a workflow if it does not exist, after signaling it.

Which SDK are you using?

Let me know if it helps,

Thanks for the fast answer.

I dont know what the SDK is, I can try to find it out later if it matters and add it to the question.

I think your answer does not entirely suit my case. I will try to explain: process2 has uncertainty whether or not process1 is already at the step where the workflow is started. It can be that process1 has not arrived there yet. In that case, I want process2 to retry at a later point in time, I do not want to start it himself.

Update: ah maybe now I realise what you mean. I think you mean that you can start a workflow with the given workflowId, with the result that you have workflow that only contains the value of the signal. It is waiting there until the first process executes the workflow method. So basically you change the order of executing the workflow method by process1 and receiving the signal by process2. Am I right there?

I will try if I can use signalWithStart here.

Hi @Mathijstb ,

I dont know what the SDK is, I can try to find it out later if it matters and add it to the question.

I just asked to provide you with some examples.

My question: is there a way to find out programmatically if the workflow has been started already?

DescribeWorkflowExecution is the best way I know to do it, it is going to throw an exception if the workflow execution does not exist, as you have mentioned.

Update: ah maybe now I realise what you mean. I think you mean that you can start a workflow with the given workflowId, with the result that you have workflow that only contains the value of the signal. It is waiting there until the first process executes the workflow method. So basically you change the order of executing the workflow method by process1 and receiving the signal by process2. Am I right there?

SignalWithStart will create a workflow execution, signal it and then start/invoke the main workflow method. Based on what you have explained, this is not gonna work for you I think.

Ok, if SignalWithStart also starts the workflow method, that is not going to work.

Our SDK version is: temporal-sdk-1.17.0

Can you give me an example how to use DescribeWorkflowExecution? Maybe that would help me to see if that is of any use.
Besides that, I am a little puzzled that I can not find a method that answers an easy question: Is there a workflow with the given id known or not? Is there a reason that there is no such method? Or is there?

One way would be to try-catch the IllegalStateException that occurs when a workflow can not be found, but I dont find that a very nice thing to do.

Sample for DescribeWorkflowExecution api here.

One way would be to try-catch the IllegalStateException that occurs when a workflow can not be found, but I dont find that a very nice thing to do.

You could externalize sending signal from client in custom method that returns true/false if its better for you.

Ok thank you very much: I tested this, and it worked to get the status of a workflow.
Now the question that remains is: how do I verify if a workflow ever started? Or is this only possible via try-and-error? For the DescribeWorkflowExecution functionality, I still get an exception if the workflow never started:

io.grpc.StatusRuntimeException: NOT_FOUND: Execution not found in mutable state:

@Mathijstb

how do I verify if a workflow ever started?
What do you mean? If the workflow method has been invoked?

Once the execution is created, the workflow execution status will be ‘Running’, even if the workflow has not made any progress (e.g if you don’t have workers polling the workflow task queue)

You can check the current workflowExecution status by accessing the status property.

DescribeWorkflowExecutionResponse desc =
                service.blockingStub().describeWorkflowExecution(
                        ...
                );
        
        System.out.println(desc.getWorkflowExecutionInfo().getStatus());

how do I verify if a workflow ever started?
What do you mean? If the workflow method has been invoked?

Yes I mean

  • if the workflow method has been invoked, I get a status (e.g. RUNNING / COMPLETED).
  • if the workflow method has not been invoked, I get an exception when trying to retrieve the status.

I want to verify (true/false) if there is a known workflow with the given workflow id, so I know I can call a @QueryMethod without running into an exception.

Depends on the rate you want to perform these checks. If it’s low then use visibility and ListWorkflowExecutions api with visibility query based on WorkflowId. In this case you will just get empty result back (no exception). If rate is high use DescribeWorkflowExecution and yes handle the not found exception in code.

For ListWorkflowExecutions, see sample here, your query could be something like

WorkflowId=‘<workflow_id>’

you’d have to check response.getExecutionsList (if null || empty) to know if no results came back.

Thank you! However I am currently trying to test this functionality in order to see how it works. And I can not get it to work yet. I get the following exception:

io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method temporal.api.workflowservice.v1.WorkflowService/ListWorkflowExecutions is unimplemented

In the example code that you linked to me in your message above, the documentations says: ‘note that this requires ES’. What is ES? I assumed that is ExecutionState, but I included it in the query below. Can you help me with a hint what I am doing wrong?

My unit test:

    @Test @Description("Check for the existence of a running workflow")
    void listWorkflow_workflowRunning() {
        var workflow2Id = "TestWorkflow2-1";
        var workflow2 = workflowClient.newWorkflowStub(TestWorkflow2.class, getWorkflowOptions(workflow2Id));
        WorkflowClient.execute(() -> workflow2.waitForMessage(5000));

        var listWorkflowExecutionsRequest = ListWorkflowExecutionsRequest.newBuilder()
                .setNamespace(workflowClient.getOptions().getNamespace())
                .setQuery(String.format("WorkflowId='%s' and ExecutionStatus=%s", workflow2Id, WORKFLOW_EXECUTION_STATUS_RUNNING))
                .build();
        var listWorkflowExecutionsResponse = service.blockingStub().listWorkflowExecutions(listWorkflowExecutionsRequest);
        System.out.println("test");
    }

@Mathijstb

io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method temporal.api.workflowservice.v1.WorkflowService/ListWorkflowExecutions is unimplemented

The method is not implemented in the test API, to list open workflows in your test you can use listOpenWorkflowExecutions. or listClosedWorkflowExecutions for closed workflows.

listWorkflowExecutions will work if you run the query connecting to a Temporal deployment, as the example shows. Here you can see the full workshop here https://www.youtube.com/watch?v=VoSiIwkvuX0

In the example code that you linked to me in your message above, the documentations says: ‘note that this requires ES’. What is ES? I assumed that is ExecutionState, but I included it in the query below. Can you help me with a hint what I am doing wrong?

ES is elasticsearch. You can run Temporal with advanced visibility or standard visibility. Advanced requires elastic search and will allow you to run SQL-like please see What is the Temporal Visibility feature? | Temporal Documentation

Thanks for the nice advice! We are using the DescribeWorfklowExecution functionality now.