如何在 praxis 中使用 EventStore 构建新的应用程序视图?

发布于 2024-11-30 10:20:12 字数 891 浏览 0 评论 0原文

是的,类似的问题之前至少被问过几次。因此我知道答案:您只需在新处理程序上重播事件即可,很简单。但尝试实际实施会引发一些问题。

我正在使用 JOlivier 的 EventStore,看起来不错。首先,我将忽略快照的概念,而只是寻找一种方法来获取我的事件。我所能做的就是这段代码:

var commitList = Store.GetFrom(DateTime.UtcNow.AddSeconds(-1));
foreach (var commit in commitList)
{
    foreach (var comittedEvent in commit.Events)
    {
        if (comittedEvent.Body is SomeDomainEvent)
            Console.WriteLine(string.Format("Found interesting event: {0}", ((SomeDomainEvent)comittedEvent.Body).Value));
    }
}

这里的第一个问题当然是:这是这样做的方法吗?我在使用“GetFrom”参数时遇到问题,因为它只是一个日期时间,而且我无法确定所有服务器在时间上都同步。如果一台服务器上的时钟比另一台服务器上的时钟慢 1 分钟怎么办?还是 ½ 小时?我还使用 NServiceBus,因此新的处理程序队列将从某个时间点开始堆积事件 - 但我如何才能 100% 确定这里没有丢失 10 秒呢?请告诉我如何从 EventStore 中获取事件,同时 100%(不是 99%)确保新的应用程序视图在启动时完全同步。

另外:您是否在代码中创建了特殊的导入方法?我的意思是,假设我的新应用程序中的处理程序在处理“SomeDomainEvent”时发出一封电子邮件。我不希望它发送所有 10,000 个旧事件的电子邮件。如何在实践/代码中进行“导入”?

Yes, something similar has been asked at least a couple of times before. Thus I know the answer: You just replay the events on the new handler, simple. But having a go at an actual implementation raises some questions.

I'm using JOlivier's EventStore which seems nice. For starters I'll ignore the concept of SnapShots and just look at a way to get my events out. All I could get going is this code:

var commitList = Store.GetFrom(DateTime.UtcNow.AddSeconds(-1));
foreach (var commit in commitList)
{
    foreach (var comittedEvent in commit.Events)
    {
        if (comittedEvent.Body is SomeDomainEvent)
            Console.WriteLine(string.Format("Found interesting event: {0}", ((SomeDomainEvent)comittedEvent.Body).Value));
    }
}

First question here is of course: Is this the way to do it? I'm having trouble using the parameter for "GetFrom" since it's just a DateTime and I can't be sure that all servers are in sync timewise. What if the the clock on one server is 1 minut behind another? Or ½ hour? I'm also using NServiceBus so the new handler queue will pile up events from a certain point in time - but how can I be 100% sure that there isn't 10 seconds missing here? Please tell me how you get events out of the EventStore while being 100% (not 99%) sure that the new application view is completely in sync when started.

Also: Do you create a special import method in your code? I mean, suppose the handler in my new application sends out an email when it handles "SomeDomainEvent". I don't want it to send out emails for all 10.000 old events. How do you do this "import" in praxis/code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝情姑娘 2024-12-07 10:20:12
  1. 添加幂等性。 Jonathan 在他有关 EventStore 项目 (v2) 的博客文章中谈到了这一点。至少一次消息传递与幂等性相结合将确保您不会处理同一消息两次。因此,延迟几分钟(甚至半小时)并不重要。您还需要将此幂等性行为集成到您的 NSB 处理程序中(例如作为第一个处理程序)。
  2. 如果您的处理程序有副作用(这看起来很奇怪,因为我觉得您正在重播以获得新的报告/视图),那么使用当前时间和事件时间来决定是否应该发送电子邮件以获取来自过去的。或者,您可以使用一个不执行任何操作的 NullEmailSender:IEmailSender 来编写处理程序(使用 IoC)(因为您知道您所在的路径是重播过去的路径之一)。
  1. Add idempotency to the mix. Jonathan talks about this in his blog posts about the EventStore project (v2). At-least once message delivery combined with idempotency will make sure you don't handle the same message twice. As such, being off by a few minutes (even a half an hour) doesn't really matter. You'd need to integrate this idempotency behavior in your NSB handlers as well (e.g. as a first handler).
  2. If your handlers have side-effects (which seems odd as I was under the impression you were replaying to get a new report/view) then there's no harm in using current time and event time to decide if emails should be sent for stuff from the past. Alternatively, you could compose your handlers (using an IoC) with a NullEmailSender:IEmailSender that does nothing (because you know the path you're on is one of replaying the past).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文