One thing that keeps causing some issues is signals somehow entering the workflow object before its workflow method was called. Seems to only happen in replay/continueAsNew scenarios.
In another thread I’ve seen a similar question that got a different answer from my observed behavior. Namely that the workflow method is always executed first up until at least its first await and that after a continueAsNew:
The workflow state will be rolled back to the state before the signal was received and signal will be delivered.
Therefore, I’d like to get some confirmation on if this is working as intended or not.
My workflow method sets a state variable, early on before calling any awaits.
My signal handler reads from this state object but, it is not set yet resulting in a NullPointerException.
For me this is quite hard to work with but moreover seems like a clear difference in how continued vs new workflows behave.
So to be clear, is the WorkflowMethod meant to execute first afer any new workflow object creation and if not how is this typically meant to be handled?
Based on this information, can I expect the same for UpdateMethod’s and their validation methods or do they provide other guarantees? I’d have a hard time validating input without any state set.
I haven’t done this myself so I hope I’m not giving bad advice here, but perhaps you could set a flag when the workflow method runs. In your signal handler, if the flag isn’t set yet, add the received signals to a queue. When the workflow method runs, process the signals from the queue, and set the flag. When the flag is set, in your signal handler process the signal immediately like you normally would.
@Robbert, the behavior you describe is expected with signalWithStart and updateWithStart. It can also happen if the workflow dispatches the signal within the first workflow task, the signal handler will be executed first. See the workflow event loop Handling Signals, Queries, & Updates | Temporal Platform Documentation
You can use @WorkflowInit to initialize the workflow variables,
add the received signals to a queue.
I also like this approach, where you add messages to the queue and, in the main workflow method, have the logic to extract and process them one by one.