From e371326a8b19b486535fc5e3deb3886bea2a2203 Mon Sep 17 00:00:00 2001 From: John Sedlak Date: Sat, 28 Feb 2026 17:11:08 -0500 Subject: [PATCH 1/3] .NET 10 upgrades, fixes --- .../JournalingTests/Grains/AccountGrain.cs | 32 ++++++--- .../Grains/AccountViewModelGrain.cs | 24 +++---- .../Grains/DelayedAccountGrain.cs | 3 + .../JournalingTests/JournalingTestFixture.cs | 1 + .../Strata.Journaling.Tests.csproj | 1 + src/Strata/JournaledGrain.cs | 67 +++++++++---------- src/Strata/Strata.csproj | 2 +- 7 files changed, 70 insertions(+), 60 deletions(-) diff --git a/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs b/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs index 45dbfb6..fd6fade 100644 --- a/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs +++ b/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Orleans.Journaling; using Strata.Journaling.Tests.JournalingTests.Events; using Strata.Journaling.Tests.JournalingTests.GrainModel; using Strata.Journaling.Tests.JournalingTests.Model; @@ -13,6 +15,9 @@ internal sealed class AccountGrain : { private readonly ILogger _logger; + + + public AccountGrain(ILogger logger) { _logger = logger; @@ -32,17 +37,17 @@ public ValueTask Deactivate() return ValueTask.CompletedTask; } - public override async Task OnActivateAsync(CancellationToken cancellationToken) - { - await base.OnActivateAsync(cancellationToken); - _logger.LogInformation("[{0}] OnActivateAsync", this.GetPrimaryKeyString()); - } + //public override async Task OnActivateAsync(CancellationToken cancellationToken) + //{ + // await base.OnActivateAsync(cancellationToken); + // _logger.LogInformation("[{0}] OnActivateAsync", this.GetPrimaryKeyString()); + //} - public override async Task OnDeactivateAsync(DeactivationReason reason, CancellationToken cancellationToken) - { - await base.OnDeactivateAsync(reason, cancellationToken); - _logger.LogInformation("[{0}] OnDeactivateAsync", this.GetPrimaryKeyString()); - } + //public override async Task OnDeactivateAsync(DeactivationReason reason, CancellationToken cancellationToken) + //{ + // await base.OnDeactivateAsync(reason, cancellationToken); + // _logger.LogInformation("[{0}] OnDeactivateAsync", this.GetPrimaryKeyString()); + //} public Task GetEvents() => Task.FromResult(Log.Select(e => e.Event).ToArray()); @@ -54,6 +59,9 @@ public async Task Deposit(double amount) var newBalance = ConfirmedState.Balance + amount; var @event = new BalanceAdjustedEvent(this.GetPrimaryKeyString()) { Balance = newBalance }; await RaiseEvent(@event); + + var vmg = GrainFactory.GetGrain(this.GetPrimaryKeyString()); + await vmg.UpdateBalance(newBalance); } public async Task Withdraw(double amount) @@ -63,5 +71,7 @@ public async Task Withdraw(double amount) var newBalance = ConfirmedState.Balance - amount; var @event = new BalanceAdjustedEvent(this.GetPrimaryKeyString()) { Balance = newBalance }; await RaiseEvent(@event); + var vmg = GrainFactory.GetGrain(this.GetPrimaryKeyString()); + await vmg.UpdateBalance(newBalance); } } diff --git a/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountViewModelGrain.cs b/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountViewModelGrain.cs index 184641c..5d36cc2 100644 --- a/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountViewModelGrain.cs +++ b/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountViewModelGrain.cs @@ -12,24 +12,24 @@ internal sealed class AccountViewModelGrain : Grain, IAccountViewModelGrain private readonly ILogger _logger; public AccountViewModelGrain( - [FromKeyedServices("state")] IPersistentState state, + [PersistentState("state")] IPersistentState state, ILogger logger) { _state = state; _logger = logger; } - public override async Task OnActivateAsync(CancellationToken cancellationToken) - { - await base.OnActivateAsync(cancellationToken); - - if(!_state.RecordExists) - { - _state.State = new(); - await _state.WriteStateAsync(); - } - - } + // public override async Task OnActivateAsync(CancellationToken cancellationToken) + // { + // await base.OnActivateAsync(cancellationToken); +// + // if(!_state.RecordExists) + // { + // _state.State = new(); + // //await _state.WriteStateAsync(); + // } + // + // } public Task GetBalance() => Task.FromResult(_state.State.Balance); diff --git a/src/Strata.Journaling.Tests/JournalingTests/Grains/DelayedAccountGrain.cs b/src/Strata.Journaling.Tests/JournalingTests/Grains/DelayedAccountGrain.cs index 2dd5006..8a16b69 100644 --- a/src/Strata.Journaling.Tests/JournalingTests/Grains/DelayedAccountGrain.cs +++ b/src/Strata.Journaling.Tests/JournalingTests/Grains/DelayedAccountGrain.cs @@ -1,4 +1,6 @@ +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Orleans.Journaling; using Strata.Journaling.Tests.JournalingTests.Events; using Strata.Journaling.Tests.JournalingTests.GrainModel; using Strata.Journaling.Tests.JournalingTests.Model; @@ -13,6 +15,7 @@ internal sealed class DelayedAccountGrain : { private readonly ILogger _logger; + public DelayedAccountGrain(ILogger logger) { _logger = logger; diff --git a/src/Strata.Journaling.Tests/JournalingTests/JournalingTestFixture.cs b/src/Strata.Journaling.Tests/JournalingTests/JournalingTestFixture.cs index 9e045b7..57d6721 100644 --- a/src/Strata.Journaling.Tests/JournalingTests/JournalingTestFixture.cs +++ b/src/Strata.Journaling.Tests/JournalingTests/JournalingTestFixture.cs @@ -33,6 +33,7 @@ static void ConfigureConsoleLogging(ILoggingBuilder logging) builder.ConfigureSilo((options, siloBuilder) => { + siloBuilder.AddMemoryGrainStorageAsDefault(); siloBuilder.UseInMemoryReminderService(); siloBuilder.ConfigureLogging(ConfigureConsoleLogging); siloBuilder.AddStateMachineStorage(); diff --git a/src/Strata.Journaling.Tests/Strata.Journaling.Tests.csproj b/src/Strata.Journaling.Tests/Strata.Journaling.Tests.csproj index 54de605..5ba8572 100644 --- a/src/Strata.Journaling.Tests/Strata.Journaling.Tests.csproj +++ b/src/Strata.Journaling.Tests/Strata.Journaling.Tests.csproj @@ -13,6 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Strata/JournaledGrain.cs b/src/Strata/JournaledGrain.cs index 97ecc80..dcebb66 100644 --- a/src/Strata/JournaledGrain.cs +++ b/src/Strata/JournaledGrain.cs @@ -1,11 +1,12 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Orleans.Journaling; namespace Strata; public abstract class JournaledGrain : - DurableGrain, IJournaledGrain, ILifecycleParticipant, IRemindable + DurableGrain, IJournaledGrain, IRemindable, ILifecycleParticipant where TModel : new() where TEvent : notnull { @@ -17,63 +18,45 @@ public abstract class JournaledGrain : private readonly Dictionary> _outboxRecipients = new(); - private ILogger _logger = null!; + private ILogger _logger = null!; private Task? _processOutboxTask; private readonly CancellationTokenSource _shutdownCancellationSource = new(); - - #region Lifecycle - public void Participate(IGrainLifecycle lifecycle) + public JournaledGrain() { - lifecycle.Subscribe>( - GrainLifecycleStage.SetupState - 1, - OnHydrateState, - OnDestroyState - ); - } - - private async Task OnHydrateState(CancellationToken cancellationToken) - { - var loggerFactory = ServiceProvider.GetRequiredService(); - _logger = loggerFactory.CreateLogger(); - - _logger.LogInformation("OnHydrateState"); - _aggregate = ServiceProvider.GetRequiredKeyedService>>("aggregate"); _journal = ServiceProvider.GetRequiredKeyedService>>("journal"); _outbox = ServiceProvider.GetRequiredKeyedService>>("outbox"); + + var loggerFactory = ServiceProvider.GetRequiredService(); + _logger = loggerFactory.CreateLogger(); + } - if (!_aggregate.RecordExists) - { - _aggregate.State = new() - { - Version = 1 - }; - - await WriteStateAsync(); - } - - OnRegisterRecipients(); + #region Lifecycle + public void Participate(IGrainLifecycle lifecycle) + { + lifecycle.Subscribe>(GrainLifecycleStage.Activate - 100, Setup, Teardown); } - protected virtual void OnRegisterRecipients() + private async Task Setup(CancellationToken cancellationToken) { - /* no op */ + OnRegisterRecipients(); + await Task.CompletedTask; } - private async Task OnDestroyState(CancellationToken cancellationToken) + private async Task Teardown(CancellationToken cancellationToken) { _shutdownCancellationSource.Cancel(); - if(_processOutboxTask is not null) + if (_processOutboxTask is not null) { await _processOutboxTask; } /* try to process the outbox */ - if(_outbox is { Count: > 0 }) + if (_outbox is { Count: > 0 }) { _logger.LogInformation("Registering reminder for outbox processing."); await this.RegisterOrUpdateReminder( @@ -82,6 +65,8 @@ await this.RegisterOrUpdateReminder( TimeSpan.FromMinutes(1) ); } + + OnCleanupRecipients(); } public async Task ReceiveReminder(string reminderName, TickStatus status) @@ -102,6 +87,16 @@ public async Task ReceiveReminder(string reminderName, TickStatus status) #endregion #region Recipient Management + protected virtual void OnRegisterRecipients() + { + /* no op */ + } + + protected virtual void OnCleanupRecipients() + { + /* no op */ + } + protected void RegisterRecipient(string key, IOutboxRecipient recipient) { _outboxRecipients.Add(key, recipient); diff --git a/src/Strata/Strata.csproj b/src/Strata/Strata.csproj index 83affef..b856d81 100644 --- a/src/Strata/Strata.csproj +++ b/src/Strata/Strata.csproj @@ -22,7 +22,7 @@ - + From 28b9ca27a4f209d0040bb18ed998a3b374021a7f Mon Sep 17 00:00:00 2001 From: John Sedlak Date: Tue, 3 Mar 2026 07:06:06 -0500 Subject: [PATCH 2/3] Version bump --- .changes/.version | 2 +- CHANGELOG.md | 7 +++++++ src/Strata/CHANGELOG.md | 7 +++++++ src/Strata/Strata.csproj | 4 ++-- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.changes/.version b/.changes/.version index 7f20734..1cc5f65 100644 --- a/.changes/.version +++ b/.changes/.version @@ -1 +1 @@ -1.0.1 \ No newline at end of file +1.1.0 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dc5f74..aa6ee57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,3 +3,10 @@ - Updates to .NET 10 - Updated to Durable State Implementation - Reworked Outbox + +## 1.1.0 + +- Updates Durable to 10.x lib +- Fixes in how outbox processing happens +- Adds optional cleanup method for recipients +- Internal unit testing fixes diff --git a/src/Strata/CHANGELOG.md b/src/Strata/CHANGELOG.md index 7dc5f74..aa6ee57 100644 --- a/src/Strata/CHANGELOG.md +++ b/src/Strata/CHANGELOG.md @@ -3,3 +3,10 @@ - Updates to .NET 10 - Updated to Durable State Implementation - Reworked Outbox + +## 1.1.0 + +- Updates Durable to 10.x lib +- Fixes in how outbox processing happens +- Adds optional cleanup method for recipients +- Internal unit testing fixes diff --git a/src/Strata/Strata.csproj b/src/Strata/Strata.csproj index b856d81..176f704 100644 --- a/src/Strata/Strata.csproj +++ b/src/Strata/Strata.csproj @@ -1,4 +1,4 @@ - + net10.0 @@ -15,7 +15,7 @@ orleans;cqrs;event sourcing https://github.com/jsedlak/strata https://github.com/jsedlak/strata - 1.0.1 + 1.1.0 From 84794e16eecc7e2f31af7f72ef83c9b14adc501c Mon Sep 17 00:00:00 2001 From: John Sedlak Date: Tue, 3 Mar 2026 07:19:59 -0500 Subject: [PATCH 3/3] Review fixes --- .../JournalingTests/Grains/AccountGrain.cs | 12 ------------ src/Strata/JournaledGrain.cs | 6 +++--- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs b/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs index fd6fade..b4c9a2b 100644 --- a/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs +++ b/src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs @@ -37,18 +37,6 @@ public ValueTask Deactivate() return ValueTask.CompletedTask; } - //public override async Task OnActivateAsync(CancellationToken cancellationToken) - //{ - // await base.OnActivateAsync(cancellationToken); - // _logger.LogInformation("[{0}] OnActivateAsync", this.GetPrimaryKeyString()); - //} - - //public override async Task OnDeactivateAsync(DeactivationReason reason, CancellationToken cancellationToken) - //{ - // await base.OnDeactivateAsync(reason, cancellationToken); - // _logger.LogInformation("[{0}] OnDeactivateAsync", this.GetPrimaryKeyString()); - //} - public Task GetEvents() => Task.FromResult(Log.Select(e => e.Event).ToArray()); public Task GetBalance() => Task.FromResult(ConfirmedState.Balance); diff --git a/src/Strata/JournaledGrain.cs b/src/Strata/JournaledGrain.cs index dcebb66..ee28355 100644 --- a/src/Strata/JournaledGrain.cs +++ b/src/Strata/JournaledGrain.cs @@ -1,5 +1,4 @@ -using Microsoft.CodeAnalysis.Operations; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Orleans.Journaling; @@ -50,7 +49,8 @@ private async Task Teardown(CancellationToken cancellationToken) { _shutdownCancellationSource.Cancel(); - if (_processOutboxTask is not null) + if (_processOutboxTask is not null && + _processOutboxTask is not { IsCompleted: true }) { await _processOutboxTask; }