How to grab values from a running Activity?

Hi,

I was wondering if there is a way to grab data while an activity is running? For example, let’s say i have a workflow that runs an activity that makes multiple external service calls. Is it possible to pass back status that is returned by one of the external calls while the activity is still running back to the workflow. In this case, the workflow would have a query method to report this data back to the user.

Let’s say the activity is a blocking call that starts something and then poll for status for completion. In the first request to start it, the external service returns data. I want to be able to access that data from a query method while its still running.

I think there are two possible ways

  • User setContextPropagate and pass the object into the activity. Within the activity, i would store the value in that object.
  • In the activity, I signal the workflow with the updated value.

Questions:

  • Is there an another way or recommended way?
  • If you go with the setContextPropagate method, Is there an example of how you get that object in the activity. I can’t find any code example for this.

Thanks,
Derek

Hi @darewreck, it seems that for your use case you could use activity heartbeat to report back its progress. In case of activity failure you can also utilize heartbeat so the activity can be retried from the last reported progress.

Let’s say, the activity makes two api calls. The first api call returns me some Id. The second call polls until the api returns a valid status of completion.

While it’s polling the status, I want my workflow to know what that id is.

How would a heartbeat help in this case?

Thanks
Derek

In that case you can signal from the activity to the workflow, here is a small sample that shows this:

Hope this helps.

It looks like your activity is performing multiple activities. So I would recommend breaking it into multiple activities. This way workflow is going to learn about the progress naturally and you can have different timeouts and retry options for each of them.

2 Likes

@maxim The issue is that now i’ll be creating an activity for each API call…I wanted to avoid thats since i’m generically generating the workflow based on a config. The activity maps to a components…but now I would have to map an activity to a component action…

btw the data itself is used strictly for monitoring and not used to make workflow decisions.

You absolutely can have a “component” that internally invokes multiple activities.

btw the data itself is used strictly for monitoring and not used to make workflow decisions.

Then don’t store it in the workflow and use an activity heartbeat to report it. The use DescribeWorkflowExecution call to retrieve values of the last heartbeat.

My current code:

  • Make api 1
  • Poll api 2 until status is complete before exiting the activity. In this case, I use a heartbeat of the status returned

From you suggestion, It sounds like

  • I should just create an object from the beginning of the activity and store that value from api call 1 + the status from the poll in the heartbeat.
  • Then I would just use the describeWorkflowExecution call to get the last heartbeat value while activity is still running.
Object {
   metadata: 
   status:
}

Thanks for the example

In this case I would absolutely recommend breaking it into two activities. One for making the API call another for polling for the status. They have completely different timeouts and retry requirements.

If there is a concern about filling workflow history or latency, etc., maybe consider a local-activity in this case?

@maxim
reaking it into two activities was something that I wanted to avoid since the DSL I created assumes one activity per component where all the functionality (request, and poll) is grouped into one activity.

Just thinking out loud

  • Using a signal could potentially pollute the history if to many calls are made, so that may not be ideal if you aren’t careful
  • Putting the data in a heartbeat would require you to make an additional call whenever you want to get the data. It’s not clear what the downside of this approach would be other than the data won’t appear in temporal UI and you have to request it. Is there any other downsides?

@sdonovan
Im not sure if I can use local-activities since some of the calls can last more then 60 seconds and from my understanding its not recommended?

DSL I created assumes one activity per component where all the functionality (request, and poll) is grouped into one activity.

I propose to change your DSL definition to support multiple activities per component. I believe that the “one activity per component” is not really a business requirement.

1 Like