# How to get the activity state at the workflow level?

**URL:** <https://community.temporal.io/t/how-to-get-the-activity-state-at-the-workflow-level/1292>\
**Category:** Community Support\
**Tags:** go-sdk, heartbeat\
**Created:** [January 12, 2021, 8:47am UTC](https://community.temporal.io/t/how-to-get-the-activity-state-at-the-workflow-level/1292 "2021-01-12T08:47:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![guntenbein](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/guntenbein/32/373_2.png) [@guntenbein](https://community.temporal.io/u/guntenbein)\
**Post date:** [January 12, 2021, 8:47am UTC](https://community.temporal.io/t/how-to-get-the-activity-state-at-the-workflow-level/1292/1 "2021-01-12T08:47:07Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [January 12, 2021, 6:11pm UTC](https://community.temporal.io/t/how-to-get-the-activity-state-at-the-workflow-level/1292/2 "2021-01-12T18:11:03Z")

</div>

From outside of workflow you can use [DescribeWorkflowExecution](https://github.com/temporalio/sdk-go/blob/9778ef5e148d747e953dc88a8dd654d6074ad417/client/client.go#L334) 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.

---

<div class="post-metadata">

**Author:** ![guntenbein](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/guntenbein/32/373_2.png) [@guntenbein](https://community.temporal.io/u/guntenbein)\
**Post date:** [March 16, 2021, 11:53am UTC](https://community.temporal.io/t/how-to-get-the-activity-state-at-the-workflow-level/1292/3 "2021-03-16T11:53:07Z")

</div>

@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.](https://github.com/guntenbein/temporal-status)

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](https://github.com/guntenbein/temporal-status/blob/main/workflow/workflow.go#L31-L47) 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](https://github.com/guntenbein/temporal-status/blob/6a7d74c4e160f99c49a2673efcb397f63bb26a63/workflow/workflow.go#L27-L34)

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!

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [March 16, 2021, 4:46pm UTC](https://community.temporal.io/t/how-to-get-the-activity-state-at-the-workflow-level/1292/4 "2021-03-16T16:46:05Z")

</div>

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).
