Skip to content

Conversation

@Aaronontheweb
Copy link
Member

Summary

Fixes health check registration in Akka.Persistence.Sql.Hosting by refactoring to use the unified API from Akka.Persistence.Hosting (v1.5.51).

Problem

Health checks were never being registered because AkkaPersistenceJournalBuilder.Build() was never called. The hosting extension methods created builder instances and assigned them to journalOpt.Adapters, but never invoked .Build(), which is responsible for:

  • Registering event adapters in HOCON
  • Registering health checks with the DI container

Solution

Refactored all WithSqlPersistence overloads to use the unified API methods:

  • .WithJournal(JournalOptions, Action<AkkaPersistenceJournalBuilder>?)
  • .WithSnapshot(SnapshotOptions, Action<AkkaPersistenceSnapshotBuilder>?)
  • .WithJournalAndSnapshot(...)

These methods properly call .Build() internally, ensuring health checks are registered.

Changes

  • Refactored bottom-level WithSqlPersistence(SqlJournalOptions?, SqlSnapshotOptions?, ...) to use unified API
  • Updated top-level overloads (with connectionString/providerName and DataOptions) to chain to bottom-level method
  • Eliminated intermediate builder assignment pattern
  • Single source of truth: all overloads now chain to one implementation

Benefits

  • ✅ Health checks now work correctly
  • ✅ Reduced code duplication (~30 lines eliminated)
  • ✅ Single source of truth for implementation
  • ✅ 100% backward compatible - all existing method signatures unchanged

Testing

  • All 9 existing tests continue to pass
  • Added BaselineJournalBuilderSpec to validate basic persistence functionality
  • Added HealthCheckSpec to verify health checks are registered and return healthy status
  • Total: 11 tests passing

Breaking Changes

None - this is fully backward compatible.

…egistration

This refactoring addresses the issue where health checks were never registered because
AkkaPersistenceJournalBuilder.Build() was never being called in the hosting extensions.

Changes:
- Refactored bottom-level WithSqlPersistence method to use Akka.Persistence.Hosting's
  unified API (.WithJournal, .WithSnapshot, .WithJournalAndSnapshot)
- Updated top-level overloads to chain to the unified implementation, eliminating
  intermediate builder assignment pattern
- The unified API properly calls .Build() internally, ensuring health checks are registered

Benefits:
- Health checks now work correctly for SQL persistence
- Single source of truth - all overloads chain to one implementation
- Reduced code duplication (~30 lines eliminated)
- Maintains 100% backward compatibility with existing method signatures

Testing:
- All 9 existing tests continue to pass
- Added BaselineJournalBuilderSpec to validate basic persistence functionality
- Added HealthCheckSpec to verify health checks are registered and healthy
- Total: 11 tests passing
…ions

- Upgrade AkkaHostingVersion from 1.5.51 to 1.5.51.1
  - This version includes the fix for issue #666 where journal health checks
    require event adapters to be registered
- Update HealthCheckSpec to verify exactly 2 health checks (journal + snapshot)
  instead of "at least one"
- Add specific assertions for both journal and snapshot health checks
- All 12 hosting tests now pass
- Update parameter names from 'journal'/'snapshot' to 'journalBuilder'/'snapshotBuilder'
- Correct version requirement to v1.5.51.1 (not v1.5.51)
- Add note about version requirement for health checks without event adapters
- Simplify code examples and fix formatting
Copy link
Member Author

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Detailed my changes

PersistenceMode mode = PersistenceMode.Both,
string? schemaName = null,
Action<AkkaPersistenceJournalBuilder>? journalBuilder = null,
Action<AkkaPersistenceSnapshotBuilder>? snapshotBuilder = null,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically a bit of a breaking change but honestly this method is awful as-is. Would be way better off deprecating and removing it - just force people to use the options types.

public static AkkaConfigurationBuilder WithSqlPersistence(
this AkkaConfigurationBuilder builder,
SqlJournalOptions? journalOptions = null,
SqlSnapshotOptions? snapshotOptions = null)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now the "source of truth" method for the rest of the calls.

journalOpt.DatabaseOptions.JournalTable.UseWriterUuidColumn = useWriterUuidColumn;
}

var adapters = new AkkaPersistenceJournalBuilder(journalOpt.Identifier, builder);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why health checks didn't work - we weren't calling down to the appropriate base method to apply the journal builder correctly.

/// <summary>
/// Validates that health checks are properly registered after the refactoring
/// </summary>
public class HealthCheckSpec : Akka.Hosting.TestKit.TestKit, IClassFixture<SqliteContainer>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validates that health checks actually get registered and run

Output?.WriteLine($" - {entry.Key}: {entry.Value.Status}");
}

// We should have exactly 2 health checks: journal and snapshot
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate that BOTH health checks (journal + snapshot store) run: this is what helped me find akkadotnet/Akka.Hosting#666

<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<AkkaVersion>1.5.51</AkkaVersion>
<AkkaHostingVersion>1.5.51</AkkaHostingVersion>
<AkkaHostingVersion>1.5.51.1</AkkaHostingVersion>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to upgrade to a newer version of Akka.Hosting to resolve the health check registration bug.

snapshot: s => s.WithHealthCheck(
unHealthyStatus: HealthStatus.Degraded,
name: "sql-snapshot"));
builder.WithSqlPersistence(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaned up the documentation some

journalOpt.DatabaseOptions.JournalTable.UseWriterUuidColumn = useWriterUuidColumn;
}

var adapters = new AkkaPersistenceJournalBuilder(journalOpt.Identifier, builder);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now use standard base methods from Akka.Hosting for this

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

Successfully merging this pull request may close these issues.

1 participant