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

Event Store Internal Improvements for 7.25 #3314

Closed
14 tasks done
jeremydmiller opened this issue Jul 17, 2024 · 0 comments
Closed
14 tasks done

Event Store Internal Improvements for 7.25 #3314

jeremydmiller opened this issue Jul 17, 2024 · 0 comments

Comments

@jeremydmiller
Copy link
Member

jeremydmiller commented Jul 17, 2024

Continuing a discussion from Discord, but gathering this all together to track outstanding tasks. The goal here is to reduce the overhead of appending events and Inline projections by reducing network round trips as much as possible. This is also to improve the new Quick Append event workflow and address #3310. This work is driven by scalability and performance concerns from two JasperFx clients concerned about scalability for very large workloads

Overarching changes:

  • Reproduce the optimization from Fetch for writing optimization for Inline projections #3290 that was backed out to make FetchForWriting() + Inline aggregates use an identity
    map when loading the aggregate to avoid multiple database round trips. This time, make this behavior "opt in"
  • Reduce the network round trips when appending events to fetch stream state and/or aggregates

Event Appending Data Fetching

When appending events, there's potentially a series of preparatory data fetching steps that has to take place before the events
can be appended and any or all inline projections can be applied. Today this feature is very optimized for appending events to a single stream at a time -- which isn't necessarily how folks are actually using this feature today. To optimize the process -- and I'm making a very large assumption that reducing the network round trips to the database will more than offset extra in process steps -- I think we make the event appending be a multi-step process to create a new intermediate helper to enable data fetching like where the active IEventAppender and each registered Inline projection have a method something like:

public interface IEventAppendingStep
{
    Task ApplyAsync(DocumentSessionBase session, CancellationToken cancellation);
}

// This would be used to register data query needs in a batch, and return a "continuation"
// that applies changes to the session later
public IEventAppendingStep FetchData(IBatchedQuery query);

There's some more detail to this so there's some interplay between Inline projections that get the stream state for you
so you don't have to make a second fetch

Tasks

  • Recreate the QuerySession.UseIdentityMapFor<T>() changes from Fetch for writing optimization for Inline projections #3290
  • Opt in for StoreOptions.Events.UseIdentityMapForInlineAggregates, with the default being false
  • FetchForWriting() using an Inline aggregate should opt into using the identity map if the above setting is true
  • Inline single stream projections should load from the identity map / session if the UseIdentityMapForInlineAggregates is turned on
  • Test FetchForWriting() + Inline + append event has the right version afterward on document w/ IRevisioned
  • Test FetchForWriting() + Inline + append event has the right version afterward on document w/ explicit version mapping
  • Make 0 be the value for quick append that means "auto-version" based on the latest. Today it's 1
  • Change to UpsertFunction to reflect the above
  • Make event operations happen before document operations like in 0630f55
  • Recreate changes to StreamAction.PrepareEvents() from 0630f55
  • DocumentMapping.UseVersionFromMatchingStream from 0630f55
  • Recreate changes to UpsertFunction from 0630f55 after the reset to 0
  • Pull in bug: Inline projections don't have correct version when appending to an existing stream (quickappend) #3310
  • Add this test:
    [Fact]
    public async Task start_and_append_events_to_same_stream()
    {
        await using var session = theStore.LightweightSession(tenant);

        session.Logger = new TestOutputMartenLogger(_testOutputHelper);

        var streamId = Guid.NewGuid().ToString();

        session.Events.StartStream<LoadTestInlineProjection>(streamId,new LoadTestEvent(Guid.NewGuid(), 1),
            new LoadTestEvent(Guid.NewGuid(), 2), new LoadTestEvent(Guid.NewGuid(), 3));
        await session.SaveChangesAsync();

        _testOutputHelper.WriteLine("APPEND STARTS HERE");

        session.Events.Append(streamId, new LoadTestEvent(Guid.NewGuid(), 4), new LoadTestEvent(Guid.NewGuid(), 5));
        await session.SaveChangesAsync();

        var doc = await session.LoadAsync<LoadTestInlineProjection>(streamId);
        doc.Version.ShouldBe(5);


    }
@jeremydmiller jeremydmiller changed the title Event Store Internal Improvements for 7.24 Event Store Internal Improvements for 7.25 Jul 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant