如何使用Rebus过滤消息?

时间:2013-04-16 18:17:19

标签: rebus

处理程序接收的每条消息都包含聚合根的整个状态。然后,系统能够基于该数据执行所需的操作。在我的场景中,根据消息中的数据授予访问权限,例如进入A&房间B.消息包含整组授权访问。 这些消息可能无序到达,因为像MSMQ这样的消息系统不保证有序交付。

消息#1授予访问房间A& A的场景。 B,但是消息#2仅允许访问房间A.如果它们无序到达,则访问被授予房间A,而后者被授予房间A& A。 B.这不是理想的结果。只能进入A房。 每条消息都包含一个时间戳,该时间戳在发布时设置。我想使用此时间戳删除无序到达的消息,例如如果消息#2在消息#1之前到达,则应丢弃消息1#。

我可以在每个处理程序方法中实现这个过滤器,但这会很乏味,所以我希望Rebus有一些EAI Message Filters的内容?

我愿意接受其他选择/实施吗?

1 个答案:

答案 0 :(得分:1)

我不确定我理解为什么你会在你的消息中传递整个聚合根,但除此之外,有一种简单的方法可以让Rebus对你的消息进行排序。

我建议您让所有邮件实现一个捕获此特定方面的公共接口,例如:

之类的东西
public interface IHaveSequenceNumber
{
    int SequenceNumber { get; }
}

然后,创建一个处理IHaveSequenceNumber的简单消息处理程序,并在遇到旧消息时中止处理程序管道,例如。

public class WillDiscardOldMessages : IHandleMessages<IHaveSequenceNumber>
{
    public void Handle(IHaveSequenceNumber messageWithSequenceNumber)
    {
        if (IsTooOld(messageWithSequenceNumber))
        {
            MessageContext.GetCurrent().Abort(); //< make this the last handler
        }
    }
}

然后 - 非常重要:) - 确保在发送开始时,您的消息过滤器始终位于处理程序管道的第一位:

Configure.With(...)
    .Transport(...)
    .SpecifyOrderOfHandlers(s => s.First<WillDiscardOldMessages>())
    .(...)

上面的IsTooOld()方法的实现我将留给您 - 如果您的端点中有一个单独的工作线程,则可能很简单,而对这些事情的并发处理并非易事。

这有意义吗?