-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft: FoldStreamAsync #89
base: master
Are you sure you want to change the base?
Conversation
There is of course more work to do on this PR (tests, documentation, I'm not even sure it's correctly using the GRPC Api), but the idea is to start a discussion. Especially about the ordering of parameters (there are good reasons for ordering them differently). About the deserializer (returning an IEnumerable or not), perf etc. (and of course take time to answer this on your work time. Sorry for posting this during the weekend) |
(seems the builds failled for another reason..) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loos good overall, just a couple of requested changes. Also needs some testing around it.
About the argument order, for now I choose the following: client.FoldAsync(deserialize, aggregator, streamname, revision, seed); the reason is that deserialize and aggregator are the most stable arguments. after that, the streamname is usually changing but for a single stream we have many revisions. The revision and seed go together, as in the FoldResult. this is a revision an a state. But to look more like the Linq Aggregate method, we could group (aggregator, seed), and (streamname,revision) .. one part being the fold part, the other the collection part.. |
Last thing I need to be validated: The function returns the Revision of the last Event read in the stream, or None if the stream is not found. This is what is expected by AppendToStreamAsync expectedRevision, right ? |
Something else... Would you recomment a NextRevision property on FoldResult to easily pass it to fold again ? (it would return Start when result.Revision is None) |
Now with better documentation, and unit tests. |
And this time, everything is green 🎉 |
To be consistent, the FoldResult.Revision would ideally always be equal to the last event StreamPosition. |
This is mainly due to the way expectedVersion is understood by AppendToStream. |
After discussing with the team it looks like we'll need to make a proto change to make this work. |
Co-authored-by: Ruben Bartelink <ruben@bartelink.com>
|
This is a proposition for a FoldStreamAsync method on the .net client.
The goal is to make it easy to both fold the stream and get the last event number.
If you don't need the last event number, it not too compicated using Linq.Async:
The reason for the SelectMany is that, this way, the serializer can return an empty list to ignore an event, or a list with multiple value when a stored event would be better splitted in several events. In most cases the list contains a single element.
It is to be noted that a check on the client.ReadAsync result is necessary to avoid an exception on NotFound stream.
When appending an event to the stream, an expected version is required, and it should be the version of the last event.
In the code above, it means adding the version number along the results of the deserializer, the in the aggregator, maintaining the last version. it also has to be fed with the seed (this is not necessarily totally valid C# syntax):
This is doable but tedious and introduce several intermediate enumerable and tuples that will bloat the GC.
This PR propose an implementation of FoldAsync including this recurring pattern in a more integrated way.
The result is a structure that contains the final value of the aggregator and the revision of the last event
If the stream is empty of not found, it returns the seen with revision None or the input revision.