【发布时间】:2015-09-17 18:54:24
【问题描述】:
假设我有一个 saga 数据,其中包含具有以下值之一的状态:
JustWaiting, AwatingPrepareDrink, WaitingForPayment
我也有不同的消息要处理,但只想在状态具有特定值时处理它们。
ie.: 仅在状态为 AwaitingPrepareDrink 时处理 PrepareDrinkMessage
为了实现这一点,我目前正在做类似的事情:
public async Task Handle(PrepareDrinkMessage message)
{
if(Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
return;
}
//do some stuff...
//state transition
Data.CurrentState = BaristaSagaData.State.WaitingForPayment;
}
我在使用这种方法时遇到的问题是,很有可能刚刚收到的传入消息很快就会收到(工作人员当前可能正在另一个处理程序中工作,该处理程序将转换到正确的状态)。
我尝试替换这个:
if(Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
return;
}
用这个:
if(Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
//too soon, try again in 10 seconds
await _bus.defer(TimeSpan.FromSeconds(10), message);
return;
}
但是,这会导致 saga 修订增加,而另一个处理程序正在做一些工作。当另一个处理程序完成时,会发生并发异常,因为同时修订版本有所增加。
有没有其他方法可以防止根据状态处理消息?
有什么方法可以在不影响修订的情况下推迟消息?
感谢您的帮助!
【问题讨论】:
-
好问题!我认为如果有可能以某种方式将传奇数据标记为“未更新”,则可以解决 - 例如类似于
MarkAsComplete()如何以秘密方式标记 saga 数据,最终将其删除,也许像MarkAsUnchanged()这样的东西可以满足您的需求......想法? -
那太棒了!我想必须明智地使用它,就像 MarkAsComplete() 一样。
标签: rebus