Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changes/.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.1
1.1.0
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 11 additions & 13 deletions src/Strata.Journaling.Tests/JournalingTests/Grains/AccountGrain.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -13,6 +15,9 @@ internal sealed class AccountGrain :
{
private readonly ILogger<IAccountGrain> _logger;




public AccountGrain(ILogger<IAccountGrain> logger)
{
_logger = logger;
Expand All @@ -32,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<BaseAccountEvent[]> GetEvents() => Task.FromResult(Log.Select(e => e.Event).ToArray());

public Task<double> GetBalance() => Task.FromResult(ConfirmedState.Balance);
Expand All @@ -54,6 +47,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<IAccountViewModelGrain>(this.GetPrimaryKeyString());
await vmg.UpdateBalance(newBalance);
}

public async Task Withdraw(double amount)
Expand All @@ -63,5 +59,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<IAccountViewModelGrain>(this.GetPrimaryKeyString());
await vmg.UpdateBalance(newBalance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ internal sealed class AccountViewModelGrain : Grain, IAccountViewModelGrain
private readonly ILogger<IAccountViewModelGrain> _logger;

public AccountViewModelGrain(
[FromKeyedServices("state")] IPersistentState<AccountViewModel> state,
[PersistentState("state")] IPersistentState<AccountViewModel> state,
ILogger<IAccountViewModelGrain> 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<double> GetBalance() => Task.FromResult(_state.State.Balance);

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -13,6 +15,7 @@ internal sealed class DelayedAccountGrain :
{
private readonly ILogger<IDelayedAccountGrain> _logger;


public DelayedAccountGrain(ILogger<IDelayedAccountGrain> logger)
{
_logger = logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static void ConfigureConsoleLogging(ILoggingBuilder logging)

builder.ConfigureSilo((options, siloBuilder) =>
{
siloBuilder.AddMemoryGrainStorageAsDefault();
siloBuilder.UseInMemoryReminderService();
siloBuilder.ConfigureLogging(ConfigureConsoleLogging);
siloBuilder.AddStateMachineStorage();
Expand Down
1 change: 1 addition & 0 deletions src/Strata.Journaling.Tests/Strata.Journaling.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
<PackageReference Include="Microsoft.Orleans.Persistence.Memory" Version="10.0.1" />
<PackageReference Include="Microsoft.Orleans.TestingHost" Version="10.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
Expand Down
7 changes: 7 additions & 0 deletions src/Strata/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
74 changes: 26 additions & 48 deletions src/Strata/JournaledGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Strata;

public abstract class JournaledGrain<TModel, TEvent> :
DurableGrain, IJournaledGrain, ILifecycleParticipant<IGrainLifecycle>, IRemindable
DurableGrain, IJournaledGrain, IRemindable, ILifecycleParticipant<IGrainLifecycle>
where TModel : new()
where TEvent : notnull
{
Expand All @@ -17,65 +17,41 @@ public abstract class JournaledGrain<TModel, TEvent> :

private readonly Dictionary<string, IOutboxRecipient<TEvent>> _outboxRecipients = new();

private ILogger<IJournaledGrain> _logger = null!;
private ILogger _logger = null!;

private Task? _processOutboxTask;

private readonly CancellationTokenSource _shutdownCancellationSource = new();


#region Lifecycle
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<JournaledGrain<TModel, TEvent>>(
GrainLifecycleStage.SetupState - 1,
OnHydrateState,
OnDestroyState
);
}

private async Task OnHydrateState(CancellationToken cancellationToken)
public JournaledGrain()
{
var loggerFactory = ServiceProvider.GetRequiredService<ILoggerFactory>();
_logger = loggerFactory.CreateLogger<IJournaledGrain>();

_logger.LogInformation("OnHydrateState");

_aggregate = ServiceProvider.GetRequiredKeyedService<IPersistentState<AggregateEnvelope<TModel>>>("aggregate");
_journal = ServiceProvider.GetRequiredKeyedService<IDurableList<EventEnvelope<TEvent>>>("journal");
_outbox = ServiceProvider.GetRequiredKeyedService<IDurableQueue<OutboxEnvelope<TEvent>>>("outbox");

if (!_aggregate.RecordExists)
{
_aggregate.State = new()
{
Version = 1
};

await WriteStateAsync();
}

OnRegisterRecipients();

var loggerFactory = ServiceProvider.GetRequiredService<ILoggerFactory>();
_logger = loggerFactory.CreateLogger<IJournaledGrain>();
}
Comment thread
jsedlak marked this conversation as resolved.

protected virtual void OnRegisterRecipients()
#region Lifecycle
public void Participate(IGrainLifecycle lifecycle)
{
/* no op */
lifecycle.Subscribe<JournaledGrain<TModel, TEvent>>(GrainLifecycleStage.Activate - 100, Setup, Teardown);
}

private async Task OnDestroyState(CancellationToken cancellationToken)
private async Task Setup(CancellationToken cancellationToken)
{

OnRegisterRecipients();
await Task.CompletedTask;
Comment thread
jsedlak marked this conversation as resolved.
}

public override async Task OnDeactivateAsync(DeactivationReason reason, CancellationToken cancellationToken)
private async Task Teardown(CancellationToken cancellationToken)
{
_shutdownCancellationSource.Cancel();
_logger.LogInformation("Shutdown initiated.");

if (_processOutboxTask is not null && !_processOutboxTask.IsCompleted)
if (_processOutboxTask is not null &&
_processOutboxTask is not { IsCompleted: true })
{
_logger.LogInformation("Waiting for outbox processing to complete.");
await _processOutboxTask;
Comment thread
jsedlak marked this conversation as resolved.
}

Expand All @@ -90,9 +66,7 @@ await this.RegisterOrUpdateReminder(
);
}

await base.OnDeactivateAsync(reason, cancellationToken);


OnCleanupRecipients();
}

public async Task ReceiveReminder(string reminderName, TickStatus status)
Expand All @@ -113,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<TEvent> recipient)
{
_outboxRecipients.Add(key, recipient);
Expand All @@ -124,20 +108,14 @@ protected async Task TryProcessOutbox()
{
if(_processOutboxTask is null || _processOutboxTask.IsCompleted)
{
_logger.LogInformation("Starting outbox processing.");
_processOutboxTask = ProcessOutbox();
}
else
{
_logger.LogInformation("Outbox processing already in progress.");
}
}

protected async Task ProcessOutbox()
{
if(_shutdownCancellationSource.IsCancellationRequested)
{
_logger.LogInformation("Shutdown in progress, skipping outbox processing.");
return;
}

Expand Down
6 changes: 3 additions & 3 deletions src/Strata/Strata.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
Expand All @@ -15,14 +15,14 @@
<PackageTags>orleans;cqrs;event sourcing</PackageTags>
<PackageProjectUrl>https://github.com/jsedlak/strata</PackageProjectUrl>
<RepositoryUrl>https://github.com/jsedlak/strata</RepositoryUrl>
<Version>1.0.1</Version>
<Version>1.1.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.3" />
<PackageReference Include="Microsoft.Orleans.Journaling" Version="9.2.1-alpha.1" />
<PackageReference Include="Microsoft.Orleans.Journaling" Version="10.0.1-alpha.1" />
<PackageReference Include="Microsoft.Orleans.Reminders" Version="10.0.1" />
<PackageReference Include="System.Memory.Data" Version="10.0.3" />
<PackageReference Include="Microsoft.Orleans.Sdk" Version="10.0.1" />
Expand Down