-
Notifications
You must be signed in to change notification settings - Fork 55
Conditionally complete workflow with atomic checking on signal or internal channel
One of the StateDecision can be conditional checking on signal/internal channel, like :
The main scenario/use case of this feature is to keep the workflow execution as short as possible, while the workflow is receiving requests from external to process (via Signal, or RPC+internalChannel). Keeping the workflow short will help reduce the cost of using Cadence/Temporal, especially if the number of the workflow is large. And it's generally easier to maintain a short workflow than a long one, for versioning workflow.
The atomic checking of channel being empty is performed on iWF server. This is to to safely ensure no racing conditions, leading to message unprocessed when completing a workflow.
However, you must be sure that there is only one state consuming the signal or internal channel that are being checked. Otherwise there could still be racing conditions.
For example, the below is a wrong usage:
InitState implement WorkflowState{ //starting State
execute(...){
return StateDecision.multiNextStates(State1.class, State2.class);
}
}
State1 implement WorkflowState{
waitUntil(...){
return CommandRequest.forAnyCommandCompleted( InternalChannelCommand.create("TEST_CHANNEL"));
}
execute(...){
return forceCompleteIfInternalChannelEmptyOrElse("TEST_CHANNEL", State1.class);
}
}
State2 implement WorkflowState{
waitUntil(...){
return CommandRequest.forAnyCommandCompleted( InternalChannelCommand.create("TEST_CHANNEL"));
}
execute(...){
return forceCompleteIfInternalChannelEmptyOrElse("TEST_CHANNEL", State2.class);
}
}
The problem is that when the channel has one message, it may happen that State1 consumes the message and also State2 checks the emptiness. Therefore, State2 will see empty channel and complete the workflow. While State1 doesn't have a chance to process the last message.