事件溯源和同步读取。可能吗?

Event Sourcing and synchronous reads. Is it possible?

只是在网上找不到任何明确的答案。我想在我的项目中使用 ES,但令我烦恼的是它的异步特性。 考虑一个协作博客站点(为了简单起见,我正在编造一些东西,因为我的领域要复杂得多)。 用户可以创建博客文章并进行编辑。就是这样,仅此而已。 所以,我刚刚用

创建了一个博客条目
createBlogEntryCommand = new CreateBlogEntryCommand(body, tags)
createBlogEntryCommand.execute()

对于 ES,我会在 ES 商店中存储 BlogEntryCreatedEvent,比如

eventStore.append({
    "id": "1d11071c-33c6-4621-bb86-cafcc3ca23a6",
    "body": "Lorem ipsum dolor sit amet....",
    "tags": ["awesome-reading", "awesome-writing"],
})

现在,我不知道消费者何时会选择并处理此事件。当然,我可以有一个启发式指标并在某种程度上保证此事件将在 X 毫秒内处理,但是如果消费者因维护而停机怎么办?我如何立即为作者提供博客条目?

果然,我可以轮询数据库以获取 1d11071c-33c6-4621-bb86-cafcc3ca23a6 的博客 ID(因为它是预先生成的,所以发布 ID 与数据库无关),一旦消费者选择了事件并在中创建了物化视图数据库,使其可供用户使用,但是 这是唯一的方法吗?

P.S. I watched a lot of videos online on the subject, I have read a ton of blogs too, but any source seems to be circumventing this caveat of ES not explaining any approaches. Most often then not, the answer I've heard "this can be resolved on UI/UX level". So if there are good books / articles / videos that are discussing how to overcome ES pitfalls in details, please share in the comments.

更新

直接读取历史同步...其实我也想过这个,但是很快就拒绝了这个想法。 考虑一个简单的待办事项应用程序,用户可以在其中注册并创建待办事项列表,我设想有类似

UserRegistered

TodoCreated

TodoUpdated

TodoCompleted

TodoDeleted

TodoUnDeleted

从事件存储中读取事件时,我对其他用户的待办事项不感兴趣,但我只对当前用户的待办事项感兴趣。这意味着要存储这样的事件:

UserRegistered {name: Bob, id: 1}

UserRegistered {name: Alice, id: 2}

TodoCreated {id: 123, todo: Buy milk, user: 1}

TodoUpdated {id: 123, todo: Buy skim milk, user: 1}

TodoCompleted {id: 123}

TodoCreated {id: 456, todo: Pay the dues, user: 2}

TodoCompleted {id: 456}

TodoDeleted {id: 123}

TodoUnDeleted {id: 123}

TodoUpdated {id: 123, todo: Buy full cream milk!, user: 1}

如果我需要获取 Bob 的待办事项 ID 123(购买牛奶)的最新状态,我需要阅读所有事件,尽管它们可能与 Bob 的项目列表无关。因此,我将遍历由 Bob 之外的其他用户创建的大量待办事项事件,以仅过滤和应用 Bob 的待办事项。

这是否意味着我将需要在我的事件存储中有一个特殊的“通道”以仅包含 Bob 对待办事项的操作。 此外,如果其他人能够管理 Bob 的待办事项列表项怎么办?如果 Alice 有权修改 Bob 的待办事项怎么办?它不会大大增加事件存储模式吗?

is it the only way?

没有

从事件存储中读取事件历史,然后使用这些事件计算您的需求视图没什么错误。

View v = View.from(events);

Does it mean I will be required to have a special "channel" in my events store to only contain Bob's actions upon todo items. In addition, what if somebody else is able to manage Bob's todo list items? What if Alice has an access to modify Bob's todos? Won't it greatly increase events storage schema?

通常的答案是属于一起的事件将共享一个关联 ID,并且消息存储允许您指定要使用的键。

例如,如果您使用 RDBMS 作为存储,您可能有一个 blob 列用于所有事件数据,然后有许多额外的列来存储对检索有用的元数据位.

访问规则(谁可以进行更改)与事件本身的上下文(事件与谁相关)是一个独立的问题。