如何处理 rebus saga 中的状态转换?
How to handle state transition inside a rebus saga?
假设我有一个包含具有以下值之一的状态的传奇数据:
JustWaiting, AwatingPrepareDrink, WaitingForPayment
我也有不同的消息要处理,但只想在状态具有特定值时处理它们。
即:仅当状态为 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;
}
但是,这会导致传奇修订增加,而另一个处理程序正在做一些工作。当另一个处理程序完成时,发生并发异常,因为修订已在此期间增加。
有没有其他方法可以防止根据状态处理消息?
有什么方法可以在不影响修订的情况下推迟消息吗?
感谢您的帮助!
我认为这是个好主意,所以我将它添加到 0.98.12,几分钟后 NuGet.org 就可以使用了。
现在您可以更改
if (Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
//too soon, try again in 10 seconds
await _bus.Defer(TimeSpan.FromSeconds(10), message);
return;
}
进入
if (Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
//too soon, try again in 10 seconds
await _bus.Defer(TimeSpan.FromSeconds(10), message);
MarkAsUnchanged();
return;
}
让我知道它是否适合你:)
这将导致加载和更新 saga 数据的管道步骤跳过更新此特定 saga 数据实例。
假设我有一个包含具有以下值之一的状态的传奇数据:
JustWaiting, AwatingPrepareDrink, WaitingForPayment
我也有不同的消息要处理,但只想在状态具有特定值时处理它们。
即:仅当状态为 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;
}
但是,这会导致传奇修订增加,而另一个处理程序正在做一些工作。当另一个处理程序完成时,发生并发异常,因为修订已在此期间增加。
有没有其他方法可以防止根据状态处理消息?
有什么方法可以在不影响修订的情况下推迟消息吗?
感谢您的帮助!
我认为这是个好主意,所以我将它添加到 0.98.12,几分钟后 NuGet.org 就可以使用了。
现在您可以更改
if (Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
//too soon, try again in 10 seconds
await _bus.Defer(TimeSpan.FromSeconds(10), message);
return;
}
进入
if (Data.CurrentState != BaristaSagaData.State.AwatingPrepareDrink)
{
//too soon, try again in 10 seconds
await _bus.Defer(TimeSpan.FromSeconds(10), message);
MarkAsUnchanged();
return;
}
让我知道它是否适合你:)
这将导致加载和更新 saga 数据的管道步骤跳过更新此特定 saga 数据实例。