我正在使用命令/消费者队列来实现扩展器模式(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?
}
}
}
答案 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}})