How to get workflowStub using runId?

I need the stub of an executing workflow to send it signals.
Can I get the stub with only runId and without WorkflowId?

HI, are you talking about testing? Do you want to test workflow code which receive signal?

The workflow id is its business identifier and is required to identify a workflow execution.

WorkflowExecution that you get from WorkflowClient.start(…) for example includes both the workflow id and its run ids. You can use it in your client / activity code to signal it:

WorkflowStub uws = client.newUntypedWorkflowStub(myWorkflowExecution, Optional.empty()); 
uws.signal("mySignalName", args);

Another thing you could do is use ListWorkflowExecution and a query for example:

String query =
        "RunId='"
            + runId
            + "' and ExecutionStatus="
            + WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_RUNNING_VALUE;

    ListWorkflowExecutionsRequest listWorkflowExecutionRequest =
        ListWorkflowExecutionsRequest.newBuilder()
            .setNamespace(client.getOptions().getNamespace())
            .setQuery(query)
            .build();
    ListWorkflowExecutionsResponse listWorkflowExecutionsResponse =
        service.blockingStub().listWorkflowExecutions(listWorkflowExecutionRequest);

    List<WorkflowExecutionInfo> executionInfo = listWorkflowExecutionsResponse.getExecutionsList();

    // should be just one or zero for the used query..
    for (WorkflowExecutionInfo wei : executionInfo) {
      WorkflowStub uws = client.newUntypedWorkflowStub(wei.getExecution(), Optional.empty());
      uws.signal("mySignalName", myArgs));
    }

Note that for this you have to have ES enabled on the Temporal server level when you start it.

Thankyou tihomir.
Your second solution is the kind of solution that i am looking for.

I think I was too brief in the question. Let me expand the use case.

My Application will spin a workflow (say wfid is W456 and runid is R123) and the workflow will make a request to an endsystem and ask it do some work. In the request I am passing run id - R123.
The endsystem will acknowdge the request (Synchronous resposne).

Post that my workflow will pause the execution untill it gets a singnal (say continueSignal).

The endsystem once the work is done will call my application back (Asynchronous response). The callback will contain the run ID.

At this point, My application needs to use the runId received in the asynchronous response and create the correspoding workflow stub and then invoke the signal (continueSignal) using the stub.

Constraits

  1. I can only pass one variable to the endsystem. Either runID or workflowId
  2. I can’t use workflow id because, my use case can have 2 workflows with the same id.

Your second solution does the job. But it is too complicated.
Is there a simpler solution?

Workflow id and run id and namespace are strings. They identify the workflow execution.
You could pass to end system a single string like

“workflowid-workflowrunid-namespace” (or use some other delimiter)

@Vikas_NS I wouldn’t recommend the second solution unless your workflow rate is very low. The list API wasn’t designed to support high query rates. So making a list query per workflow is an anti-pattern.

  1. I can only pass one variable to the endsystem. Either runID or workflowId
  2. I can’t use workflow id because, my use case can have 2 workflows with the same id.

The solution is to not use RunId to identify workflows. Use WorkflowID instead. Temporal doesn’t allow having multiple workflows with the same id. So you constraint is not really valid.

Hi Maxim,
I understand that we can’t have 2 workflows with same wfid running. Our usecase invovles reuse of workflow id. So we can have few completed workflows and a running one with the same workflow id.

Based on your recommendation we have decided not to use the second solution.
We will use both runId and worklfowId to create the stub.

Thankyou.

1 Like