How to get the activity state at the workflow level?

I would like to have a way to get the state (percentage of completeness or other) from an activity to the workflow. So the workflow can return it as the part of a query to the workflow or use it for reasoning on the rest of the execution. Now I see two ways:

  1. Activity heartbeats can have some data (percentage or any other). But I cannot find a way to read about the activity heartbeats from the workflow.

  2. Signals. An activity can signal some data to the workflow as some milestones reached by the activity (every 10 percent, for example). And the workflow will be able to read the data and reason or send it as the result of the query.

What is the best way to do this?

From outside of workflow you can use DescribeWorkflowExecution call that returns all pending activities information including data included in the last heartbeat.

I would go with the signal approach you described if the workflow has to take action based on activity reaching a certain milestone.

@maxim, thanks for the answer! I am experimenting with the signal approach now in GitHub - guntenbein/temporal-status: The project will explore the possibilities to have workflow status for Temporal engine.

It is not clear what is the best way to receive the signals from activities in a correct way. Now I use workflow.Await() inside the workflow.Go() temporal-status/workflow.go at main · guntenbein/temporal-status · GitHub and it works, the coroutine finishes so there are no memory leaks. But there is the comment for the Await : Do not mutate values or trigger side effects inside condition.

There was another way, but it blocked the goroutine (-> memory leak): temporal-status/workflow.go at 6a7d74c4e160f99c49a2673efcb397f63bb26a63 · guntenbein/temporal-status · GitHub

The ReceiveAsync of the channel cannot be used because of the Coroutine panics as blocked. It happens because ReceiveAsync does invoke yeld() for the coroutine state.

Any advice will be appreciated!

1 Like

Agree that the Await approach is not correct as it mutates the workflow state from the condition function.

The second approach with blocking on the Channel.Receive looks fine to me. I’m not sure why you treat the goroutine as a memory leak. When the workflow completes it will be cleaned up as well.

Another more common approach is to use Selector that listens on multiple channels and Futures (which can be results of activity and child workflow invocations).