Can I attach a listener to workflow execution?

Is there a way to listen for workflow execution state?


So as in temporal UI there’s a status column, I want to get this status in my code and then depending on status run corresponding logic. I’ve been thinking of putting all workflows in a list and then iterating over it and checking each workflow status, but that seems fairly inefficient. So can I attach a listener to a workflow execution? If I can’t, can you please give a me a better idea on how to accomplish this task.
Thanks in advance!

One way could be to use ListWorkflowExecutions request as shown here for example. You can set the query for specific workflow type and then check each execution status.

Another possible way you could do this is via client interceptors, You can register a client interceptor via WorkflowClientOptions, for example:

WorkflowClientOptions workflowClientOptions =
        WorkflowClientOptions.newBuilder().setInterceptors(new MyClientInterceptor()).build();
    WorkflowClient client = WorkflowClient.newInstance(service, workflowClientOptions);

SDK provides the OpenTracingClientInterceptor you can see for how to implement your own.

If in your code you start your workflows async with for example:

WorkflowClient.start(workflow::exec);

and then later on get results via untyped stub getResult, in your client interceptor you could do for example:

@Override
  public <R> GetResultOutput<R> getResult(GetResultInput<R> input) throws TimeoutException {
    try {
      return super.getResult(input);
    } finally {
     // check the status here using DescribeWorkflowExecutionRequest
      // you can get  WorkflowExecution from input.getWorkflowExecution()
      
    }
  }

Hope this helps, if you can provide more details on what exactly you are trying to do we can see if there are any more options for it.

Thank you for your response! The second option seems like a way to go. What I’m trying to do is that I have a workflow for creating and order and then processing it. If the order fails to create in the external service I retry the activity for 2 hours. If retry continues to fail I need to change order status and run some logic. Do you think there’s a better way to do it? So basically whenever a workflow is failed I need to run some logic

If retry continues to fail I need to change order status and run some logic.

I think you can do this with your workflow business logic. After activity retries are exhausted you can catch ActivityFailure in your workflow code, and handle it accordingly (for example run some compensation activities as your logic, or even continueAsNew as a new workflow run if you wanted). Also it sounds as you are polling an external service for results, see this forum thread for best practices for polling (and we are atm creating Java samples for each described options, will link here when that’s done).

How do I determine if retry attempts are exhausted? Since I do not specify max attempts, only threshold. Thanks for the links tho!

How do I determine if retry attempts are exhausted?

Activity invocations always throw ActivityFailure (child workflows ChildWorkflowFailure). This is delivered to your workflow code after retries are exhausted.

For activity timeouts I’d suggest watching this video (for you it’s recommended to limit retries via scheduleToClose activity timeout which includes retries, rather than setting a hard-coded max attempt limit).

So in your workflow code you could do:

try {
   activity.doSomething();
} catch (ActivityFailure e) {
   // ActivityFailure will have ApplicationFailure as its cause (activity errors are converted to ApplicationFailure)
     ApplicationFailure appFailure = (ApplicationFailure) e.getCause();
   // you can get the original failure type via appFailure.getType and message via appFailure.getOriginalMessage()
   }
}

If you are executing your activities async, you can also catch ActivityFailure when you call .get on your returned Promise.

1 Like

Thank you so much good sir!