Understanding how workflow "Replay" is working

I am learning Temporal and usign Java SDK.

Trying to understand how the workflow is being “replayed” upon a worker continuing the workflow execution.

I read the The SDK and Temporal Cluster relationship section of the docs. If I got it right, after a successful exection of an activity by a worker, the results are stored, a new event is created in the task queue - and a new available worker is allocated to continue the workflow execution.

For that worker: what will be the “entry point” (in Java code) for the execution? Will it call the workflow method (i.e. method that calls activities and glues things together)? Is it correct to assume that the “replay” means that if an activiity was previosly executed, the SDK is smart to take the results?

I tried to verify the idea (using “Money Transfer” sample) by adding a log print to the 1st line:

public void transfer(String fromAccountId, String toAccountId, String referenceId, double amount) {

System.out.println(“Hello World!”);
account.withdraw(fromAccountId, referenceId, amount);
account.deposit(toAccountId, referenceId, amount);

When running the worker in my environment, I saw only one “Hellow World!” log, so seems like the method is executed only once.

Am I missing something essential? Or is it a development server only behavior? Can anyone provide an in-depth execution flow of the app code when replay is performed?

Thanks in advance.

We have tested that when the current execution running on a worker is terminated, the workflow replay is triggered by the history events.

In such cases, the replay will be executed on the same or another worker, and the workflow method will be called again. However, any steps or code calls in this method that have already been captured in the event history will not reach the actual activity or other Temporal external events. This is because the replay will advance to the Java line code that was not captured in the event history, and the replay will continue from there.

For instance, if an activity is already captured in the event history, the workflow method code that calls it will just receive the output of the activity captured in the history.

If the code is changed and the execution path does not match the stored event history, the workflow replay will terminate with an error stating that the workflow method code is inconsistent with the history.

Hello, thanks for your help!
Unfortunately, I still have a fundamental gap to cover.

From the documentation I mentioned, it appears like when a worker executing a workflow needs to call an activity, an event is added to the task queue, and the current worker is terminated. Once the activity was successfuly executed, [potentially] another worker continues the workflow, and as you write, “the workflow method will be called again”. [in my specific case, the workflow method is ‘transfer’]

If that’s the case, the log being placed on the 1st line of the workflow method - will be executed after the 1st activity [in my case: withdraw] will be executed, and before getting to the 2nd activity [in my case: deposit]. However, in the test, I see only one log message . It looks like the workflow method [in my case: transfer] is continued from the same place it was stopped, and not like the workflow method was called again by another worker.

What am I missing?


Now I learned that there is a concept of “Sticky execution”, an optimization that perfers the same worker (if available) to resume any workflow execution.
Is it correct to say that in the case of “Sticky execution” the workflow code continues from the place it was blocked, while if the worker is not the “sticky one” - the execution begins from the 1st line of the workflow method?
If so, “Sticky execution” explains why the method is called only once, so the log prints out only once.

It is highly optimized. I did a lot of debugging and validated that the workflow method thread is not killed on each activity call. It is only killed if there is a need to free resources, such as when the workflow method hits Temporal sleep for a long time or encounters other similar events.

Also, use the Temporal Slf4J wrapper for Java, as it stores the logs in the history and does not log them if the workflow needs to be replayed.

For instance: final Logger log = Workflow.getLogger(MyWorkflowImpl.class);