命令

时间:2018-12-12 10:23:06

标签: events elixir cqrs event-sourcing commanded

Event Storedefined a while ago的作者格雷格·杨(Greg Young),其关联ID引用了根本原因,而因果关系ID引用了消息的直接原因。

因此,您应该能够通过另一条消息的因果ID找到一条消息,而另一条消息是另一条消息的直接响应。而且,您应该能够通过相同的因果ID查找同一会话中的所有消息。

如果应用此模式,则会话中的第二条消息应同时将相关性ID和因果关系ID设置为第一条消息。

在《命令》中,我希望第一个事件同时具有相关性ID和因果关系ID,以指向导致事件发生的命令(也用视觉方式描述here)。

在Commanded自己的事件存储中,令人困惑的是,命令之后的第一个事件具有不同的相关性和因果关系ID。因此,看来Commanded并不适用Greg Young的定义。

我的问题是,“命令”中这些ID的确切定义是什么?是否有意识地决定不遵循格雷格·杨(Greg Young)的定义?如果是,为什么?

1 个答案:

答案 0 :(得分:1)

Commanded已按照指南中的说明实施了correlation and causation ids,复制如下。

默认情况下,命令不会保留,因此,除非您也保留传入的命令,否则您无法遵循命令>事件>命令的原因和影响链。您可以使用Commanded audit middleware将分派的命令存储到任何受Ecto支持的数据库中。这样做将使您可以将命令及其结果事件联系在一起。假设您在分派命令时正在复制它们,则相关ID也可用于关联所有相关消息。下面有一个这样做的例子。

在Greg的事件存储中,我认为因果关系ID是从事件复制到事件的,而忽略了中间命令,因为他的事件存储仅存储事件。


相关性和因果关系ID

为帮助监视和调试已部署的应用程序,跟踪命令和事件的因果关系和关联ID非常有用。

  • causation_id-导致事件或导致命令分派的事件的命令的UUID。
  • correlation_id-用于关联相关命令/事件的UUID。

您可以在调度命令时设置因果关系和相关ID:

:ok = ExampleRouter.dispatch(command, causation_id: UUID.uuid4(), correlation_id: UUID.uuid4())

在事件处理程序中调度命令时,应从正在处理的事件中复制这些值:

defmodule ExampleHandler do
  use Commanded.Event.Handler, name: "ExampleHandler"

  def handle(%AnEvent{..}, metadata) do
    %{event_id: causation_id, correlation_id: correlation_id} = metadata

    ExampleRouter.dispatch(%ExampleCommand{..},
      causation_id: causation_id,
      correlation_id: correlation_id
    )
  end
end

将根据源域事件自动为进程管理器调度的命令分配适当的因果关系和相关性ID。