From 5c69422a1d6d0858d6a199efa43c2d3ab7d729f0 Mon Sep 17 00:00:00 2001 From: Alexander Zeitler Date: Tue, 4 Jun 2024 01:31:43 +0200 Subject: [PATCH] docs: sample how to wait for non-stale projections from IHost --- docs/events/projections/async-daemon.md | 31 +++++++ .../event_projections_end_to_end_ihost.cs | 88 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 src/DaemonTests/event_projections_end_to_end_ihost.cs diff --git a/docs/events/projections/async-daemon.md b/docs/events/projections/async-daemon.md index 40773d8f72..fe37a3781c 100644 --- a/docs/events/projections/async-daemon.md +++ b/docs/events/projections/async-daemon.md @@ -237,6 +237,37 @@ The basic idea in your tests is to: There is also another overload to wait for just one tenant database in the case of using a database per tenant. The default overload **will wait for the daemon of all known databases to catch up to the latest sequence.** +### Accessing the daemon from IHost: + +If you're integration testing with the `IHost` (e.g. using Alba) object, you can access the daemon and wait for non stale data like this: + + + +```cs +[Fact] +public async Task run_simultaneously() +{ + var host = await StartDaemonInHotColdMode(); + + StoreOptions(x => x.Projections.Add(new DistanceProjection(), ProjectionLifecycle.Async)); + + NumberOfStreams = 10; + + var agent = await StartDaemon(); + + // This method publishes a random number of events + await PublishSingleThreaded(); + + // Wait for all projections to reach the highest event sequence point + // as of the time this method is called + await host.WaitForNonStaleProjectionDataAsync(15.Seconds()); + + await CheckExpectedResults(); +} +``` +snippet source | anchor + + ## Diagnostics The following code shows the diagnostics support for the async daemon as it is today: diff --git a/src/DaemonTests/event_projections_end_to_end_ihost.cs b/src/DaemonTests/event_projections_end_to_end_ihost.cs new file mode 100644 index 0000000000..d72a4ed8a2 --- /dev/null +++ b/src/DaemonTests/event_projections_end_to_end_ihost.cs @@ -0,0 +1,88 @@ +using System.Linq; +using System.Threading.Tasks; +using DaemonTests.TestingSupport; +using JasperFx.Core; +using Marten; +using Marten.Events; +using Marten.Events.Projections; +using Microsoft.Extensions.Logging; +using Shouldly; +using Xunit; +using Xunit.Abstractions; + +namespace DaemonTests; + +public class event_projections_end_to_end_ihost : DaemonContext +{ + public event_projections_end_to_end_ihost(ITestOutputHelper output) : base(output) + { + _output = output; + } + + #region sample_accessing_daemon_from_ihost + + [Fact] + public async Task run_simultaneously() + { + var host = await StartDaemonInHotColdMode(); + + StoreOptions(x => x.Projections.Add(new DistanceProjection(), ProjectionLifecycle.Async)); + + NumberOfStreams = 10; + + var agent = await StartDaemon(); + + // This method publishes a random number of events + await PublishSingleThreaded(); + + // Wait for all projections to reach the highest event sequence point + // as of the time this method is called + await host.WaitForNonStaleProjectionDataAsync(15.Seconds()); + + await CheckExpectedResults(); + } + + #endregion + + private Task CheckExpectedResults() + { + return CheckExpectedResults(theSession); + } + + private async Task CheckExpectedResultsForTenants(params string[] tenants) + { + foreach (var tenantId in tenants) + { + await using (var session = theStore.LightweightSession(tenantId)) + { + await CheckExpectedResults(session); + } + } + } + + + + private async Task CheckExpectedResults(IDocumentSession session) + { + var distances = await session.Query().ToListAsync(); + + var events = (await session.Events.QueryAllRawEvents().ToListAsync()); + var travels = events.OfType>().ToDictionary(x => x.Id); + + distances.Count.ShouldBe(travels.Count); + foreach (var distance in distances) + { + if (travels.TryGetValue(distance.Id, out var travel)) + { + distance.Day.ShouldBe(travel.Data.Day); + distance.Total.ShouldBe(travel.Data.TotalDistance()); + } + else + { + travel.ShouldNotBeNull(); + } + + Logger.LogDebug("Compared distance " + distance); + } + } +}