使用 rebus 和 MSMQ 取消挂起作业或执行作业的最佳策略是什么?(长时间运行)



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

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

根据不做不必要的工作对你来说有多重要,我可以想到几种方法在处理开始之前中止它。

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

如果你的工作是由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,例如,通过将bool填充到数据库的某个地方。


PS: IMessageContext上的AbortDispatch()函数可从0.98.11

获得

相关内容

  • 没有找到相关文章

最新更新