0

我正在推理事件溯源,并且经常遇到先有鸡还是先有蛋的问题。将不胜感激有关如何对此进行推理的一些提示。

如果我执行所有 I/O 绑定处理异步(即写入事件日志),那么我如何处理,有时甚至检测失败?

我正在使用 Akka Actors,因此每个事件/消息的处理都是顺序的。我目前没有任何数据库,而是将所有事件保存在事件日志中,然后将所有事件的聚合状态保存在内存中的模型中。查询都是针对这个模型的,你可以认为它是一个缓存。

例子

创建新用户:

  1. 验证用户在模型中不存在
  2. 将事件持久化到日志
  3. 更新模型(在内存中)

如果第 3 步中断,我仍然坚持我的活动,以便以后重播。如果第 2 步中断,我也可以优雅地处理它。

这很好,但是由于第 2 步是 I/O 绑定的,我认为我应该在单独的参与者中执行 I/O 以释放第一个参与者进行查询

在允许查询的同时更新用户(A0 = 前端/GUI 参与者,A1 = 处理器参与者,A2 = IO 参与者,E = 事件总线)。

  1. (A0->E->A1) 发布事件以更新用户“U1”。验证用户“U1”是否存在于模型中
  2. (A1->A2)将事件持久化到日志(单独的参与者)
  3. (A0->E->A1->A0) 查询用户 'U1' 个人资料
  4. (A2->A1) 事件现在持续更新模型
  5. (A0->E->A1->A0) 查询用户“U1”个人资料(现在返回新数据)

这很吸引人,因为查询可以在 I/O 以自己的节奏进行的同时进行处理。

但是现在我可以给自己造成各种问题,我可以将两个不兼容的命令(删除然后更新)持久化到事件日志中,并在以后重播时崩溃,因为我在持久化事件之前进行了验证然后更新模型。

我的目标是围绕我的模型进行简单的推理(因为 Actor 按单线程顺序处理消息),但在查询时不等待 I/O 绑定更新。我觉得我正在建模一个数据库,这本身可能是一个问题。

如果事情不清楚,请写评论。

4

1 回答 1

0

异步 I/O 可以与事务更新共存。如果你在命令之后发送一个“ACK”或“NACK”,那么你就可以了解它是否发生了。在分布式或真正异步的模型中,“NACK”很可能来自显式故障和超时。

于 2012-10-17T02:06:30.467 回答