事件处理程序应该是即发即忘
Should event handlers be fire and forget
处理程序处理命令操作后,我引发域事件。在某些情况下,事件处理程序失败是可以容忍的。我可以说大多数人都是这种情况,我希望所有事件处理程序都可以容忍失败。
如果事件处理程序失败,我的操作是否应该失败,或者事件处理程序是否应该触发并忘记?
例如,假设这是我引发事件的地方,如您所见,来自 eventHandler.Execute
的潜在异常未得到处理。
public void Publish<TEvent>(TEvent @event) where TEvent : IDomainEvent
{
IEnumerable<IEventHandler<TEvent>> handlers = _lifetimeScope.GetService<IEnumerable<IEventHandler<TEvent>>>();
var eventHandlers = handlers as IEventHandler<TEvent>[] ?? handlers.ToArray();
if (eventHandlers.Any())
{
foreach (IEventHandler<TEvent> eventHandler in eventHandlers)
{
eventHandler.Execute(@event);
}
}
else
{
throw new InvalidOperationException("No handler registered");
}
}
但是,我的愿望是拥有如下内容:
public void Publish<TEvent>(TEvent @event) where TEvent : IDomainEvent
{
IEnumerable<IEventHandler<TEvent>> handlers = _lifetimeScope.GetService<IEnumerable<IEventHandler<TEvent>>>();
var eventHandlers = handlers as IEventHandler<TEvent>[] ?? handlers.ToArray();
if (eventHandlers.Any())
{
foreach (IEventHandler<TEvent> eventHandler in eventHandlers)
{
try
{
eventHandler.Execute(@event);
}
catch (Exception ex)
{
// log the expection
// swallow it
}
}
}
else
{
throw new InvalidOperationException("No handler registered");
}
}
我通常将事件放在持久的 pub/sub 系统上,然后 return 来自命令处理程序。
这样,单个事件处理程序可以在不影响主系统或彼此的情况下失败。
处理程序处理命令操作后,我引发域事件。在某些情况下,事件处理程序失败是可以容忍的。我可以说大多数人都是这种情况,我希望所有事件处理程序都可以容忍失败。
如果事件处理程序失败,我的操作是否应该失败,或者事件处理程序是否应该触发并忘记?
例如,假设这是我引发事件的地方,如您所见,来自 eventHandler.Execute
的潜在异常未得到处理。
public void Publish<TEvent>(TEvent @event) where TEvent : IDomainEvent
{
IEnumerable<IEventHandler<TEvent>> handlers = _lifetimeScope.GetService<IEnumerable<IEventHandler<TEvent>>>();
var eventHandlers = handlers as IEventHandler<TEvent>[] ?? handlers.ToArray();
if (eventHandlers.Any())
{
foreach (IEventHandler<TEvent> eventHandler in eventHandlers)
{
eventHandler.Execute(@event);
}
}
else
{
throw new InvalidOperationException("No handler registered");
}
}
但是,我的愿望是拥有如下内容:
public void Publish<TEvent>(TEvent @event) where TEvent : IDomainEvent
{
IEnumerable<IEventHandler<TEvent>> handlers = _lifetimeScope.GetService<IEnumerable<IEventHandler<TEvent>>>();
var eventHandlers = handlers as IEventHandler<TEvent>[] ?? handlers.ToArray();
if (eventHandlers.Any())
{
foreach (IEventHandler<TEvent> eventHandler in eventHandlers)
{
try
{
eventHandler.Execute(@event);
}
catch (Exception ex)
{
// log the expection
// swallow it
}
}
}
else
{
throw new InvalidOperationException("No handler registered");
}
}
我通常将事件放在持久的 pub/sub 系统上,然后 return 来自命令处理程序。
这样,单个事件处理程序可以在不影响主系统或彼此的情况下失败。