Closed ugumba closed 1 year ago
My thought was to bring the cache to the lower level (event reader) because it will cover both OO and functional.
@alexeyzimarev, that looks a bit awkward to me, as IEventReader knows only about events, not the state (or aggregate). Would you cache the events instead of the state?
Also, I assume you mean the event store, as the cache should be updated with the new events/state, otherwise the next command would have to redundantly re-apply the most recent event(s).
AggregateStore ("OO") and FunctionalCommandService/FoldedEventStream ("functional") are the two current structures which instantiate state, fold in past events and store new events. Without a larger refactoring, I'm not sure how to cache closer to the event reader.
(Frankly, I don't quite understand the motivation for FunctionalCommandService - you've basically reimplemented CommandService/Aggregate
In general, I'd assume that we should avoid referencing the full event stream as much as possible - or we're guaranteed to create a scalability problem. (That's the reason for #218, but I think it is equally undesirable in FoldedEventSteam.)
Edit: fixed typo
I am not sure what you mean by FunctionalCommandStore
as it doesn't exist.
Yeah, you are right about the reader as it only knows about events. My, maybe irrelevant, concern is that the aggregate is nothing more than a set of functions. The persisted part of it is the state object. I think it is ok to cache aggregates only for now, I will figure out the rest later.
I am not sure what you mean by
FunctionalCommandStore
as it doesn't exist.
Sorry about the typo, I've corrected to FunctionalCommandService.
I think it is ok to cache aggregates only for now, I will figure out the rest later.
The proposed use of IMemoryCache caches state and version (in a Snapshot
Definitely best to cache state+version - this might be relevant https://github.com/jet/equinox/blob/master/src/Equinox.Core/Caching.fs https://github.com/jet/equinox/blob/master/src/Equinox.Core/Cache.fs
Something tells me that caching and snapshotting are very close conceptually. Yes, snapshotting implies serialisation, but so does caching in a distributed store like Redis.
I would also attempt to avoid changing the existing signatures in favour of composition. I realise it might not be possible with the current implementation, so some changes might be required in different abstractions.
I've had to move on - my fork will remain if anyone wants to consider picking this up again, or would like to discuss.
This builds on #218 and #219, and adds support for IMemoryCache in AggregateStore, using StreamName as key and Aggregate.Snapshot as value.
Edit: also added to FunctionalCommandService. I'm not using this myself, but it was fairly straightforward. In general, the repo needs aligning on int vs long/ulong for versions/positions.