复杂的工作聚合

时间:2017-04-04 13:41:34

标签: cqrs event-sourcing

我有一个非常复杂的工作流程,并不是100%清楚我在哪里处理什么。 我不想要代码,只是负责什么的问题。

鉴于以下内容:

  1. 有一个根目录" C:\ server"
  2. 里面有两个目录" ftp"和"备份"
  3. 想象一下以下过程:

    1. 外部客户将文件发送到ftp目录。
    2. 导入器应用程序获取文件,现在就开始了。
    3. 必须为此文件创建作业聚合。
    4. 命令" CreateJob(字符串文件)"被解雇了。 ?。该文件必须从ftp移动到备份。在CommandHandler内部或在Aggregate内部还是在JobCreated事件上?
    5. StartJob(Guid jobId)被叫。必须创建第三个文件夹"正在进行中#34;,必须将文件从备份复制到正在进行中。是谁?
    6. 因此,如果没有正确的文件系统,如果Aggregate无法正常工作,那么我不清楚文件系统必须处理的位置。 因为我的第一种方法是在基础结构层/ lib中执行此操作,该层侦听来自作业层的事件。但似乎不是100%正确吗?!

      最重要的是,重播是什么? 你不能重放被移动的东西/文件,你必须以某种方式模拟客户将文件发送到ftp文件夹......

      感谢答案

2 个答案:

答案 0 :(得分:1)

  

我有一个非常复杂的工作流程,并不是100%清楚我在哪里处理什么。我不想要代码,只是负责什么的问题。

通常的答案是域名模型 - 又名"聚合"做出决定并保存它们。观察这些决定,一些事件处理程序会引起副作用。

  

最重要的是,重播是什么?您无法重播移动的内容/文件,您必须以某种方式模拟客户将文件发送到ftp文件夹...

您将事件重播到聚合,以便将其恢复到最后决定的状态。这是重播副作用的另一个问题 - 这是处理其他地方副作用的动机的一部分。

当然,在可能的情况下,您希望副作用具有幂等性,以便重复的消息不会产生问题。但请注意,从模型的角度来看,副作用是否成功实际上并不重要。

答案 1 :(得分:1)

  

必须将文件从ftp移动到备份。在CommandHandler内部或在Aggregate内部还是在JobCreated事件上?

在这种情况下,我将文件移动到Application服务中的目标文件夹,该服务将命令发送到Aggregate(或者在Aggregate上调用类似命令的方法}},它是相同的)在命令发送之前Aggregate。这样,如果文件系统存在一些问题(没有足够的权限或空间不可用等),则不发送命令。这些问题不应该到达Aggregate。我们最保护它免受基础设施的影响。事实上,我们应该将Aggregate与其他任何事物隔离开来;它必须包含纯粹的业务逻辑,用于决定生成哪些事件。

  

因为我的第一种方法是在Infrastructure层/ lib中执行此操作,该层侦听来自作业层的事件。但似乎不是100%正确吗?!

事实上,这对我来说似乎过于工程化了。你必须亲吻。

  

StartJob(Guid jobId)被叫。必须创建第三个文件夹"正在进行中#34;,必须将文件从备份复制到正在进行中。谁做到了?

StartJob被调用之前,无论是谁调用StartJob都可以进行移动。再次,保持Aggregate纯。在这种情况下,它取决于您的框架/域详细信息。

  

最重要的是,重播是什么?您无法重播移动的内容/文件,您必须以某种方式模拟客户将文件发送到ftp文件夹...

事件从事件存储加载并在两种情况下重放:

  1. 在每个命令发送到Aggregate之前,Aggregate Repository会加载事件存储中的所有事件,然后每个命令应用到{ {1}},可能在Aggregate上调用了一些Aggregate方法。所以,这种方法应该没有任何副作用(纯粹),否则你会在每次执行命令时一次又一次地改变 并且你不想要那样。

  2. 向用户显示数据的applyThisEvent(TheEvent)read-modelsprojections)会侦听这些事件并更新包含用户看到的数据的数据库表。这些事件在生成后以及每次重新创建读取模型时都会发送到这些读取模型。当您发明新的query-models时,您必须将之前由read-model生成的所有事件传递给它,以便在它们上构建正确/完整的状态。如果您的阅读模型的事件监听器有副作用,那么当您重播那些漫长的过去事件时,您认为会发生什么?外面的世界一次又一次地被修改,你不想要那样!阅读模型只解释事件,不会产生其他事件,也不会改变外部世界。

  3. 当事件到达另一种类型的模型aggregates时,会有一个特殊的第三种情况。 Saga 必须只收到一次活动!这是您考虑在Saga中使用的情况。 可以在您的情况下执行此操作,但不是KISS。