【问题标题】:What's the best strategy for cancelling a pending job or executing job using rebus and MSMQ? (long running)使用 rebus 和 MSMQ 取消挂起作业或执行作业的最佳策略是什么? (长时间运行)
【发布时间】:2015-12-13 08:57:27
【问题描述】:

我有一个 Web 应用程序通过 rebus 发送消息以在远程计算机上启动长时间运行的作业。我正在使用 MSMQ 传输。远程工作者可以并行处理 5 个操作。因此,如果远程工作人员很忙,一些消息可能会堆积在队列中,直到工作人员可以处理它们。同时,用户可能决定取消挂起的操作(或正在执行的操作)。在使用 rebus(或任何总线)时,处理这种特殊情况的最佳策略是什么?

【问题讨论】:

    标签: msmq rebus


    【解决方案1】:

    好吧,由于队列是不透明的,并且端点只能看到它实际尝试接收的消息,因此实际上没有办法在收到消息之前对其进行过滤。

    根据您不做不必要的工作对您的重要性,我可以想出几种方法来在处理开始之前中止处理。

    我能想到的一种方法是利用 Rebus 在 handler pipeline 中执行处理程序这一事实,这意味着您可以在消息被执行之前拦截它们。

    如果您的工作是由DoWork 执行的,您可以像这样插入“过滤器”:

    Configure.With(...)
        .(...)
        .Options(o => o.SpecifyOrderOfHandlers()
            .First<AbortIfCancelled>()
            .Then<DoWork>())
        .Start();
    

    然后您的 AbortIfCancelled 可能如下所示:

    public class AbortIfCancelled : IHandleMessages<Work>
    {
        readonly IMessageContext _messageContext;
        readonly ICancelWork _cancelWork;
    
        public AbortIfCancelled(IMessageContext messageContext, ICancelWork cancelWork)
        {
            _messageContext = messageContext;
            _cancelWork = cancelWork;
        }
    
        public async Task Handle(Work work)
        {
            if (await _cancelWork.WasCancelled(work))
            {
                _messageContet.AbortDispatch();
            }
        }
    }
    

    因此,如果ICancelWork 事物返回 true,则中止管道的其余部分。然后,您将必须实施 ICancelWork 例如通过将布尔值填充到某个数据库中。


    PS:IMessageContext 上的 AbortDispatch() 功能可从 0.98.11 开始使用

    【讨论】:

    • 想到了类似的东西。尽管这会引入共享数据,但我想这可能值得考虑,具体取决于您提到的做不必要工作的重要性。我会试一试!再次感谢。
    猜你喜欢
    • 2022-01-05
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多