我尝试在Rebus中沿着大纲http://mookid.dk/oncode/archives/3043尝试简单的延迟消息超时模式,以便根据我是否从其他连接的服务收到及时响应来获得其他行为同一辆公共汽车。代码已被修改为使用async / await。 (是的,我知道那篇文章真的是关于单元测试。我只是尝试相同的超时事件)
我案例中的处理程序是一个传奇。等待两个消息发送操作作为启动saga的消息的处理程序的最后两个调用。第一条消息使用来自外部服务的请求/回复,并且最终也在同一个传奇中处理回复。 第二条消息是延迟消息,应该在超时发生时强制执行备用操作,就像在Rebus单元测试示例中一样。我已经验证了消息是由saga / handler发送和接收的,没有任何问题。它看起来像这样:
public class TestSaga : Saga<TestSagaData>, IAmInitiatedBy<SomeMessage>, IHandleMessages<SomeReply>, IHandleMessages<TimeOutMessage>
{
private readonly IBus _bus;
public TestSaga(IBus bus)
{
_bus = bus;
}
protected override void CorrelateMessages(ICorrelationConfig<TestSagaData> config)
{
config.Correlate<SomeMessage>(s => s.Identifier, d => d.OriginalMessageIdentifier);
config.Correlate<SomeMessage>(s => s.Tag, d => d.CorrelationIdentifier);
config.Correlate<SomeReply>(s => s.Tag, d => d.CorrelationIdentifier);
config.Correlate<TimeOutMessage>(s => s.Tag, d => d.CorrelationIdentifier);
}
public async Task Handle(SomeMessage message)
{
if (!IsNew)
return;
Data.CorrelationIdentifier = message.Tag;
Data.OriginalMessageIdentifier = message.Identifier;
Data.ReplyReceived = false;
await _bus.Send(new SomeRequest {Tag = message.Tag});
await _bus.Defer(TimeSpan.FromSeconds(30), new TimeOutMessage() {Tag = message.Tag});
}
public async Task Handle(SomeReply message)
{
// Even if we would get here loooong before...
Data.ReplyReceived = true;
await DoStuffIfNotTimedout();
}
public async Task Handle(TimeOutMessage message)
{
// ...this, DoStuffIfTimeout below is always called
// since state is preserved from the _bus.Defer call. Correct?
if (!Data.ReplyReceived)
await DoStuffIfTimedout();
}
private async Task DoStuffIfNotTimedout()
{
// some more async stuff here
MarkAsComplete();
}
private async Task DoStuffIfTimedout()
{
// some more async stuff here
MarkAsComplete();
}
}
我添加了一个布尔传奇数据标志/属性,表示首先收到对第一条消息的回复,最初在两次await Send / Defer调用之前将其设置为false 并在回复的消息处理程序中立即将其设置为true。 该标志应该用于防止超时操作启动,以防在第一个回复之后但在后续操作完成之前收到延迟超时事件并且标记已完成。
然而,在这种情况下,传奇的状态似乎跟随&#39;收到的消息。因此,如果首先输入第一个消息回复处理程序并将saga数据标志设置为true。然后,当稍后输入延迟消息处理程序时, 有些东西再次重置了标志,似乎忽略了第一个回复处理程序中的操作(将标志设置为true)。不确定&#39; Revision&#39;传奇的数量应该改变与否,但它似乎总是保持不变(零)。 还要注意,如果在输入回复处理程序很久之后发生超时并不重要,当输入超时处理程序时,该标志为“错误”。
这是传奇的国家行为吗?我认为saga状态会以某种方式在消息处理程序调用之间保持不变。如果它是错误的行为,可能会导致什么? 我对Rebus很新,所以我确定我在这里误解了一些东西但在这种情况下我想知道::)。
引擎盖下使用的运输是RabbitMQ。
测试代码:saga state test