Skip to content
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

Feat: Pointers #45

Merged
merged 23 commits into from
Jul 1, 2022
Merged

Feat: Pointers #45

merged 23 commits into from
Jul 1, 2022

Conversation

the-avid-engineer
Copy link
Member

@the-avid-engineer the-avid-engineer commented Jun 26, 2022

It would be useful for the ISnapshotRepository, IEntityRepository, and IProjectionRepository instances to be able to get entities at any version instead of always pulling the latest version.

To that end, introduce a new value object, the pointer:

public record Pointer(Id Id, VersionNumber VersionNumber);

For ISnapshotRepository, mark the existing GetSnapshot method as obsolete and forward the call to the new GetSnapshotOrDefault method, which accepts a Pointer instead of an Id

For IEntityRepository and IProjectionRepository, mark the existing GetCurrent and GetAtVersion methods as obsolete and forward the call to the new GetSnapshot method, which accepts a Pointer instead of an Id

Affected Snapshot Repository Implementations

Redis

The Redis snapshot key will be changed from {keyNamespace}#{snapshotId} to {keyNamespace}#{snapshotPointer.Id}@{snapshotPointer.VersionNumber}

In Memory

The in-memory snapshot repository will simply use Pointer as the dictionary key instead of Id

Additional Changes

Transaction Subscribers

The TransactionSubscriber has been buffed in non-test mode. Instead of calling Task.Run and ignoring the result, it will now add the result to a BufferBlock. (Note: Test mode still uses Task.Run(...).Wait() so that transactions are processed synchronously.) In addition, the transaction subscriber will be registered as a BackgroundService and will process the BufferBlock asynchronously. This processor is also try-catched, so any failed processes will not cause the background service to stop.

Entity & Projection Snapshot Transaction Subscribers

The entity snapshot subscriber and projection snapshot subscriber have been refactored to implement ITransactionProcessor and are registered using TransactionProcessorSubscriber. The two processors have a common base class which abstracts some redundant work and also provides a caching mechanism to avoid hitting the database multiple times.

You also must provide a transaction session options name now, as it is possible to hit the database if snapshots don't have all of the information needed.

Entity & Projection Repositories

These repositories will no longer return the default snapshot state - if the expected pointer cannot be loaded, they will always throw SnapshotPointerDoesNotExistException (which replaces the EntityNotCreatedException that was originally thrown on the now-obsolete GetCurrent method)

Entity, Projection and Snapshot - Common Library Interfaces

Some common functionality between IEntity<> and IProjection<> (e.g., GetId, GetVersionNumber, Construct) have been moved to the ISnapshot<> interface, and these common library interfaces now extend ISnapshot<>

ISnapshot<> has two new method, ShouldRecord and ShouldRecordAsLatest, the latter of which replaces the now-obsolete ShouldReplace

Projections

The IProjectionStrategy interface has been removed - the functionality has been moved to the IProjection<> interface, more or less. To accomplish this, there are two methods:

  1. GetProjectionIdOrDefault - this will statically map an object to an Id?
  2. GetCommandQuery - this will dynamically map the projection and projection pointer to any query you want - it should load all of the commands which are needed to reach the projection pointer.

Because you now control the query, the GetEntityVersionNumber method has been removed.

to start.. it is going to be beneficial to make projections have a GetId and GetVersionNumber method added because projections can be snapshots, and the aim of this PR is to use the new "pointer" concept to address snapshots.. now, in the common library, both an entity and a projection are intended to be used with snapshots - there's quite a bit of code for snapshots that works with both! to that end, let's just formalize the relationship and move the common methods (Construct, GetId, GetVersionNumber) to the ISnapshot interface and refactor all of the resulting redundancies
always uses minimum version number, useful for getting most recent snapshot with little code
@the-avid-engineer the-avid-engineer linked an issue Jun 26, 2022 that may be closed by this pull request
@the-avid-engineer the-avid-engineer added diff:remove Pull Request removes an existing feature diff:deprecate Code has been marked as obsolete, but still works diff:refactor:internal Code has been refactored in a way that will not cause compiler errors labels Jun 27, 2022
@the-avid-engineer the-avid-engineer self-assigned this Jun 27, 2022
@the-avid-engineer the-avid-engineer marked this pull request as ready for review June 27, 2022 03:52
@the-avid-engineer the-avid-engineer merged commit a47623f into main Jul 1, 2022
@the-avid-engineer the-avid-engineer deleted the feat/pointers branch July 1, 2022 04:24
@the-avid-engineer the-avid-engineer added this to the 7.0.0 milestone Jul 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
diff:deprecate Code has been marked as obsolete, but still works diff:refactor:internal Code has been refactored in a way that will not cause compiler errors diff:remove Pull Request removes an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Store Multiple Snapshot Versions
1 participant