如何在事件采购中记录/实现对象状态?
我正在解决一个看起来很简单的问题,但是在发生暴风雨的情况下,我不确定应该如何完成实施。
我有一个诸如Dropbox之类的应用程序,用户可以上传文件,并且在这些文件之上,用户可以运行一系列操作,以修改其内容。还可以更改该文件的名称或将其移至另一个位置。
我想跟踪文件的lastupdatimestamp
及其原因,所有这些更新均通过fileupdated
事件完成。 - 例如:
用户上传文件,
fileupdated
在过程结束时wevent看起来像{“ fileId”:“ 1234556”:“ 1234556”,“ lastUpdateTtimestamp”:“ 202222 -06-08 10:50:00“,“原因”:“ FileUploaded”}
。用户将某些内容写入文件,
fileupdated
在过程结束时的事件看起来像{“ fileId”:“ 1234556”,“ lastupdatedTimestamp”:“ 2022-06 -08 11:00:00“,”原因”:“ FileContentModified”}
。
等等。
我不确定如何在我的文件
对象的事件中保持此更新历史记录。我在此示例中还没有汇总,我认为filestatus
可以提供此更新历史记录,但我并没有完全相信。
I'm solving a problem that might seem simple, but in event storming I'm not sure how the implementation should be done.
I have an application that works like dropbox, the user get to upload files and on top of those files the user can run a series of operations that will modified the content of it. There is also the possibility to change the name of that file or move it to another location.
I want to track the LastUpdatedTimestamp
of the file and the reason of it, and all these updates are done via a FileUpdated
event. - for example:
A user uploads a file, the
FileUpdated
wevent at the end of the process would look like{"fileId": "1234556", "LastUpdatedTimestamp": "2022-06-08 10:50:00", "reason": "FileUploaded"}
.A user writes something to a file, the
FileUpdated
event at the end of the process would look like{"fileId": "1234556", "LastUpdatedTimestamp": "2022-06-08 11:00:00", "reason": "FileContentModified"}
.
and so on.
I'm not really sure how to keep this update history in event storming for my File
object. I don't have an aggregate in this example yet, and I thought that a FileStatus
could provide this update history but I'm not fully convinced.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我发现通常会在发生暴风雨中记录什么事实是有帮助的:这使得通过系统追踪信息流变得更加容易。我个人更喜欢一种类似于事件采购的方法,称为事件建模,这是技术的核心部分。
因此,如果我们注意到
fileupdated
事件包含更新
timestamp,并且还要注意更新的文件,我们也可以制定一种行为驱动的规格绘制了汇总的内容,也许“如果我们发布命令,则会导致fileupdated(file =“ foo”,updateTate =“ 2022-06-09 20:00”)
,命令>获取更新的最后一次文件“ foo”应导致日期不早于“ 2022-06-09 20:00”。请注意,这可以在没有汇总提示的情况下进行配制,尽管它确实暗示了
fileupdated的命令(file =“ foo”,...)
event和命令获得最后更新时间文件“ FOO”需要反对相同的汇总,因为这是唯一没有假设基础架构的唯一方法,而不是进行事件采购以获得该一致性保证所需的唯一方法。该汇总可能是一个文件,甚至可以在一天内是一个文件,也可以是汇总的每个文件(例如,您决定要命令对所有文件进行修改,因为某些给定的文件修改文件以非常一致)。一旦您拥有汇总,在汇总中如何表示状态是一个实现细节,可以说是一种优化,可以使您免于重播每个事件。
因此,对于“获取“ foo”的最后一次,“ foo”已更新“命令”命令,一个只是时间戳就足够了:通过事件进行迭代,当您找到
fileupdated(file =“ foo”,...)时
以更新
时间戳和您正在累积的时间戳的最大值(这甚至具有成为CRDT:事件迭代可以按任何顺序进行)。当然,当您添加事件和相关的行为规范时,显而易见的优化是结合一个在一种类型的事件上键入的事件手柄,以便您一次迭代事件,而不是随着行为的行为变化,而不是几次。I find it's usually helpful in event storming to record what facts are in the event: it makes it easier to trace the flows of information through the system. I personally prefer a methodology similar to event sourcing called event modeling, where that's a core part of the technique.
So if we notate that the
FileUpdated
event contains anupdatedAt
timestamp and also notes which file was updated, we can formulate a sort of behavior-driven spec even if we haven't mapped out what the aggregates are, perhaps "if we issue a command which results in aFileUpdated(file = "foo", updatedAt = "2022-06-09 20:00")
, a command to get the last time file "foo" was updated should result in a date no earlier than "2022-06-09 20:00"".Note that this can be formulated without a hint of the aggregates, though it does imply that the command resulting in a
FileUpdated(file = "foo", ...)
event and the command to get the last time file "foo" was updated need to be against the same aggregate, because that's the only way without assuming more of the infrastructure than is necessary to do event sourcing to get that consistency guarantee. That aggregate could be a file, it could even be a file over a day or it the aggregate could be every file (for instance, you decide that you want a command to get all files modified since some given file was modified to be strongly consistent).Once you have the aggregates, how the state is represented within the aggregate is an implementation detail and arguably just an optimization to save you from replaying every event.
So for the "get the last time "foo" was updated" command, a state that is just a timestamp is sufficient: iterate through the events and when you find a
FileUpdated(file = "foo", ...)
take the max of theupdatedAt
timestamp and the timestamp you're accumulating (this even has the advantage of being a CRDT: the event iteration can happen in any order). Of course, as you add events and associated behavior specifications, the obvious optimization is to combine event-handlers that are keyed on one type of event so you iterate through the events once instead of several times as the behavior being exercised changes.