Hello,
Documentation says There is no need in explicit synchronization because multi-threaded code inside a workflow is executed one thread at a time and under a global lock.
There is also the following documentation in DeterministicRunner.java:
/**
* Executes a runnable in a specially created workflow thread. This newly created thread is given
* chance to run before any other existing threads. This is used to ensure that some operations
* (like signal callbacks) are executed before all other threads which is important to guarantee
* their processing even if they were received after workflow code decided to complete. To be
* called before runUntilAllBlocked.
*/
void executeInWorkflowThread(String name, Runnable r);
With this code:
private final List<Object> jobQueue = new ArrayList<>();
@WorkflowMethod
@Override
public void executeCreateTree(@Nonnull List<Object> jobQueue) {
this.jobQueue.addAll(jobQueue.getJobsList());
Workflow.await(() -> this.jobQueue.size() > 0);
Object jobToExecute = this.jobQueue.get(0);
this.jobQueue.remove(0);
if (this.jobQueue.size() > 0) {
Workflow.continueAsNew(this.jobQueue);
} else {
// Exit workflow
}
}
@Override
@SignalMethod
public void scheduleCreateTree(@Nonnull Object jobInfo) {
this.jobQueue.add(jobInfo);
}
How does Temporal Java SDK guarantee that jobQueue did not change between this.jobQueue.size() > 0
and Workflow.continueAsNew(this.jobQueue);
lines? DeterministicRunner documentation indicates that SignalMethod will be given a chance to run before workflow completes. And that would indicate that last signal could be lost as workflow would decide to exit.
In general it is possible for thread to be interrupted in between those 2 lines. In a typical java application I would put both if-clause and Workflow.continuesAsNew inside of a single critical section. But it seems to be not recommended here.
Could you please advise?