In Place Copy-Replace
See original GitHub issueHi,
Weāve been using Eveneum as part of our event-sourced application for a while now and so far it has served us well š Thank you @jkonecki !
Over-time weāve started applying upcasters to convert old event-schemas to new ones (in-memory, at runtime), but weāve reached the point where weād like to apply a migration to our store to remove some of these old version and reduce our upcasting code.
To perform this migration we were drawn to an āin place copy-replaceā strategy as described in Versioning in an Event Sourced System by Gregory Young. The way weād like to tackle this is as follows:
- The events are upcasted to their latest version using our existing upcasting code
- The upcasted version of these events are added to the same stream (hence āin placeā, since it uses the same stream)
- Additionally, weād add 2 āaudit eventsā, one before and one after the upcasted events respectively (e.g.
CopyReplaceStarted
andCopyReplaceFinished
).- The purpose of these is to provide insight in what occurred within the stream for anyone who might check the stream in the future.
Our event consumers are running asynchronously and are heavily reliant on the āCosmos DB Change Feedā. This means that:
- We prefer not to update any āoldā event document (as this would trigger the changes to appear in the change feed). So weād rather not flag them as being āsoft deletedā.
- In the future we might remove the āoldā event documents completely, but to avoid problems with asynchronous processing we donāt want to delete them right away.
To be able to accomplish our flavor of in place copy-replace, weāve found that weād need the following features:
- Adding MetaData to the StreamHeader containing the new starting point of the stream
- This is already possible with Eveneum š
- The ability to read the metadata of a stream before reading the actual stream. This would allow us to determine where the stream starts, to then only start reading from that point (skipping the clutter from the past).
- Reading the header of a specific stream is currently problematic. There seems to only be a way to read multiple headers using
LoadStreamHeaders
. This problem would probably be fixed ifReadHeader
onEventStore
was madepublic
(instead ofprivate
)
- Reading the header of a specific stream is currently problematic. There seems to only be a way to read multiple headers using
- Finally, weād need 2 ways of reading a stream from a specific version. One that ignores all Snapshots, so that we could perform a 2nd copy-and-replace starting from a position in the stream. And a second that takes Snapshots into account and so reads as little events as possible (stopping at the first snapshot), to keep our aggregate loading efficient.
- This is currently not possible because
ReadStreamFromVersion
ignores the snapshots, andReadStream
doesnāt have an option to read from a certain point. To accomplish this, weād need a combination of these 2 methods. As an example, this could be an optionalRequestOptions
onReadStream
(similar to the Cosmos API), where theRequestOptions
exposes the following options:bool IgnoreSnapshots
(false
for rehydration of aggregates,true
when reading the entire stream to perform a migration)ulong? Version
(to avoid loading events from before the copy-replace migration)
- This is currently not possible because
Weāre willing to contribute to Eveneum in the form of a PR to add these missing features. But before we start working on this, we wanted to first ask:
- What is your opinion about our approach?
- Are you open to PRās that would add the features weāre missing?
- Is there something we should keep in mind?
Thank you in advance!
Issue Analytics
- State:
- Created 2 years ago
- Comments:24 (24 by maintainers)
Top GitHub Comments
Could you please rename
AsOfVersion
property on the options class toToVersion
? I think it may be a more clearer alternative, especially when compared toFromVersion
.Thank you very much for your kind words, Thomas!
I understand your challenges regarding change feed subscribers.
Your suggestions make sense and Iām happy to accommodate them.
Please give me a moment to think about naming convention and approach regarding
ReadStream
method - Iāll come back to you by tomorrow.If youāve already made some code changes than please start a PR - if not than please wait for feedback from me.
Please rest assured that Iām happy with the approach youāre proposing and will help with getting the new version out as soon as I can.
On Mon, 29 Nov 2021, 18:14 ThomasVandenbon, @.***> wrote: