Does Workflow.await() always re-evaluate before signal is processed?

I have a workflow which is started using executeUpdateWithStart. This update method calls Workflow.await(() → stopWaiting), waiting for some condition to return from the update method.. The workflow thread will eventually set stopWaiting = true, then call some activity or await again, finishing the update method. A separate signal comes in and will set stopWaiting = false. I have 2 questions regarding this:

1. Even if the signal is running on a separate thread, it will never execute before the main workflow thread yields control and it only yields control once it calls some temporal sdk function (await, activity call, etc), which finishes the current workflow task. Is this correct?

  1. Since the condition was modified in the current workflow task, is the await condition guaranteed to be re-evaluated before the main thread yields control and the signal starts? Is it ever possible that the main thread sets stopWaiting = true, signal starts which sets stopWaiting = false, then the await condition gets re-evaluated?
  1. Correct. Temporal SDK uses cooperative multi-threading.
  2. Yes, the condition is guaranteed to be reevaluated after any of the threads made any progress.

Awesome! Thanks for the confirmation. And just to clarify when you say any of the threads made any progress, is progress defined as completing a workflow task? So the condition would always be re-evaluated at the end of the workflow task before the task completion event?

Or is it more accurate to say any temporal sdk action since threads handling signals and updates don’t complete workflow tasks but they can call await, activities, or just complete?

At any time of workflow execution a thread is either newly created or is blocked on some Temporal API like sleep/await. If the thread was woken up and unblocked and executed some code and then blocked on another API, then it made some progress. If it didn’t unblock, then it didn’t make any progress.

Makes sense. Thanks so much maxim!

Another question on this. If a workflow thread is blocked due to an activity call and a signal/update arrives, will the signal/update only start executing once the activity completes? Or can it start executing at anytime before/during/after since the workflow thread has yielded control?

Also clarifying on the point:

2. The await condition is guaranteed to be re-evaluated after any thread makes progress.

Let’s say update1 is waiting on a condition. Workflow thread sets the condition which will break the wait of update1. Another update2 came in and is waiting to execute. Is it also guaranteed that update1 will be executed before update2 since it was affected by the progress of the workflow thread?

The event loop diagram ( Handling Signals, Queries, & Updates | Temporal Platform Documentation ) just states that after the workflow thread yields the loop will progress any signals/updates. So it seems possible that update2 can start executing before update1.

This is the logic of the code in question with the condition I’m wondering about.

boolean finishUpdate = false;

void workflow() {
    // stuff
    finishUpdate = true;
    // activity
}

String update1() {
    Workflow.await(() -> finishUpdate);
    return "update1 done";
}

String update2() {
    finishUpdate = false;
    return "update2 done";
}
  1. update1() is called using executeUpdateWithStart.
  2. update1() calls await and yields control.
  3. workflow() runs and sets finishUpdate = true.
  4. workflow() calls an activity and yields control.
  5. update2() arrives and is waiting to be run.
  6. update1() await condition is re-evaluated after workflow() made progress,
    but is not yet scheduled for execution.
  7. update2() gets scheduled before update1().
  8. update2() sets finishUpdate = false, finishes execution and yields control.
  9. update1() await condition is re-evaluated after update2() made progress.
  10. finishUpdate = false and update1() hangs.

Can step 6 happen or is the thread always run after re-evaluation? If so, what is the order if multiple threads are affected by the condition?