Rebus-从Handle方法退出应用程序

时间:2019-06-26 12:29:05

标签: rebus

我正在使用命令/消费者队列来实现扩展器模式(https://www.enterpriseintegrationpatterns.com/patterns/messaging/DataEnricher.html),其中消费者是扩展器,并将扩展后的消息发布到单独的端点(在这种情况下为SQL数据库)。使用者作为实现取消令牌的HostedService运行。

因为我正在使用一种传输方式中的命令,然后将事件发布到另一种传输中,所以我正在发布的传输方式可能会关闭,而我正在使用的传输方式则会启动。在这种情况下,我想记录一个错误并停止我的托管服务。但是,由于调用Handle方法已处理异常,因此我看不到它将如何工作,并且无法访问取消令牌。有人有什么想法吗?

这是我想做的事情的草稿。

    public async Task Handle(EditedEventData message)
        {
            var enricher = _enricherFactory.GetEnricher(message);
            object @event = await enricher.EnrichAsync(message);

            var transformers = _transformerFactory.GetTransformers(message);
            var messages = new List<object>();

            foreach (var transformer in transformers)
            {
                messages.AddRange(transformer.Transform(@event, message));
            }

            foreach (var item in messages)
            {
                try
                {
                    await _bus.Publish(item);
                }
                catch (Exception ex)
                {
                    _logger.LogCritical("Publishing event message {@item} failed with error {ex}", item, ex);
                    //how do I exit from here?
                }
            }
        }

1 个答案:

答案 0 :(得分:1)

如果我是你,我会提供某种应用程序服务,例如IApplicationControlService,您可以配置为使用您使用的任何IoC容器将其注入处理程序。

它可能看起来像这样:

public interface IApplicationControlService
{
    void RequestApplicationShutdown();
}

然后您的代码就可以

public class YourHandler : IHandleMessages<EditedEventData>
{
    readonly IApplicationControlService applicationControlService;

    public YourHandler(IApplicationControlService applicationControlService)
    {
        this.applicationControlService = applicationControlService;
    }

    public async Task Handle(EditedEventData message)
    {
        // (...)

        foreach (var item in messages)
        {
            try
            {
                await _bus.Publish(item);
            }
            catch (Exception ex)
            {
                _logger.LogCritical("Publishing event message {@item} failed with error {ex}", item, ex);

                applicationControlService.RequestApplicationShutdown();
            }
        }
    }
}

在出现错误时请求停止应用程序。

IApplicationControlService的实现可能类似于

public class BruteForceApplicationControlService : IApplicationControlService
{
    public void RequestApplicationShutdown()
    {
        Environment.FailFast("you should probably not do THIS ?");
    }
}

或更温和的something –关键是,您将能够提供一种方法来请求您的应用程序“从外部”关闭,最有可能从组装应用程序的位置(即{ 3}})