Let's assume I've got a saga data containing a state with one of the following values:
JustWaiting, AwatingPrepareDrink, WaitingForPayment
I also a have different messages to handle, but only want to handle them when the state has a particular value.
ie.: Handle PrepareDrinkMessage only when state is AwaitingPrepareDrink
To achieve this, I'm currently doing something like that:
public async Task Handle(PrepareDrinkMessage message)
{
if(Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
return;
}
//do some stuff...
//state transition
Data.CurrentState = BaristaSagaData.State.WaitingForPayment;
}
The problem I'm having with this approach is that it's quite possible that the incoming message what just received a little to soon (the worker is possibly currently doing work in another handler that will transition to the correct state).
I tried replacing this:
if(Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
return;
}
with this:
if(Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
//too soon, try again in 10 seconds
await _bus.defer(TimeSpan.FromSeconds(10), message);
return;
}
However, this causes the saga revision to increase while another handler is doing some work. When the other handler finishes, a concurrency exception occurs because the revision has increased in the meantime.
Is there any other way to prevent handling a message according to state?
Is there any way to defer messages without impacting the revision?
Thanks for your help!