Workflows Variables & Activities

Have some questions on Workflows & Activities
I understand that in a workflow, all variables and threads are stored/persisted and activities encapsulate external unreliable services.

  1. Should all workflow variables be Serializable? What kind of serialization is used here?
  2. Does Temporal persist the input and output of an Activity as well?
  3. Is thread persistence achieved through variable persistence and rebuilding the state using event sourcing?
  4. In a decision step between two activities, if the decision is made on an external state, should that call also be encapsulated in an activity?

Should all workflow variables be Serializable? What kind of serialization is used here?

Workflow variables are not required to be serializable as workflow state is rebuilt in the case of failure by replaying events in the workflow execution history (event sourcing). But if you use a workflow variable as input to an activity or return it in response to query handler, then it needs to be serializable.

Does Temporal persist the input and output of an Activity as well?

Yes. All activity input parameters are serialized and stored within ActivityScheduledEvent in execution history.

Is thread persistence achieved through variable persistence and rebuilding the state using event sourcing?

I’m not sure I fully understand the question. The only restriction Temporal puts on workflow logic is, that it needs to be deterministic. Temporal SDK also has a scheduler which executes multi-threaded code in deterministic manner. In the case of failure we replay your workflow code using execution history and considering it is deterministic we end up exact same state along with all threads, local variables and call-stack.

In a decision step between two activities, if the decision is made on an external state, should that call also be encapsulated in an activity?

Anything which pulls in state from external source needs to be called within Activity or LocalActivity.

In one of the previous discussions, it was mentioned that when the system is loaded threads could be removed to make resources available for other executions. When a removed thread comes back into action, I guess the states are replayed to continue the execution.

Lets say I make a rest callA. Based on its return value, I would like to decide between callB and callC. I guess all calls needs to be wrapped inside an activity to make it deterministic.

The calls to A, B and C have to be inside the activities. The logic that decides which activity to call based on data should reside inside the workflow.

1 Like

I am also not 100% sure how this works.

Let’s say during the first run the rest call returns status β€œa”, then somewhere on the next lines the worker dies and the workflow will be replayed. This time, the rest call would return status β€œb” if it was called, but my understanding is that return status β€œa” from
the previous call is persisted and the rest call will not be made again. So the replay actually happens with an old (stale) state.

@maxim Is this assumption correct?

Trying to understand how the input parameters or the activity result get serialized in golang? Do you look for specific interface method?

@nadilas Yes, the assumption is correct. On replay the activities are not reexecuted and their results are taken from the history.

Serialization is fully pluggable. It is done by implementing a PayloadConverter interface.

The default serialization uses JSON format. See encoding/json package documentation for details.