Skip to content

AOT: module serializer table for Akka.Cluster (#8626, part 3a) - #8666

Merged
Aaronontheweb merged 4 commits into
akkadotnet:devfrom
Aaronontheweb:feature/aot-m2-3a-cluster-serializers
Sep 30, 2026
Merged

Aaronontheweb merged 4 commits into
akkadotnet:devfrom
Aaronontheweb:feature/aot-m2-3a-cluster-serializers

Conversation

@Aaronontheweb

Copy link
Copy Markdown
Member

Part 3a of #8626. Follows #8658's module-table pattern for Akka.Cluster, the core cluster assembly. Tools, Sharding, DistributedData and Metrics follow in a companion PR (part 3b) to keep each PR reviewable; the two touch the same block of ModuleSerializerTable.Default and will conflict trivially on merge.

Changes

  • ClusterSerializers (Akka.Cluster.Serialization) is Cluster's first ModuleSerializers table. It covers every serializers and serialization-bindings row in Cluster.conf: ClusterMessageSerializer (id 5) and ReliableDeliverySerializer (id 36, alias reliable-delivery).
  • Core's module map gets one more entry: "Akka.Cluster", passing a type-name literal to Load.
  • IDeliverySerializable (Akka.Delivery.Internal) lives in Akka.dll, not Akka.Cluster.dll, but Cluster.conf binds it to reliable-delivery. It's listed in ClusterSerializers.BoundTypes and resolves the same way Remote's System.String binding does: through the "modules this config loaded" lookup, not the module's own assembly.

Constructor choices

Both classes have exactly one constructor, and Cluster.conf has no serialization-settings block for either alias, so the factory calls the class's only constructor directly:

Alias Class Constructor Why
akka-cluster ClusterMessageSerializer (system) only ctor; no settings block
reliable-delivery ReliableDeliverySerializer (system) only ctor; no settings block

No public API changes. No IVT changes: Akka already grants Akka.Cluster and Akka.Cluster.Tests access to its internals, and IDeliverySerializable is public.

Behavior with the switch on (recorded in BREAKING_CHANGES_V1.6.md)

Same shape as #8658, measured against this module specifically:

  • A serialization-settings.<alias> block for either serializer now builds it instead of throwing MissingMethodException, since neither constructor takes a Config.
  • Constructor exceptions are no longer wrapped in TargetInvocationException.
  • With the switch off, both rows -- and IDeliverySerializable's binding -- now resolve instead of throwing ConfigurationException.

A versioned name for a different Akka.Cluster version resolves both ways; reflection already accepted one.

Tests

ClusterSerializersSpec (Akka.Cluster.Tests) runs in a DynamicTypeLoadingCollection (non-parallel) and derives from AkkaSpec with ITestOutputHelper, reusing ModuleSerializerSpecs (Akka.Tests.Shared.Internals.Xunit3) for the shared checks:

  • Table matches config, both directions: AssertTableMatchesConfig -- the table's Serializers/BoundTypes name exactly the types Cluster.conf's rows name.
  • Akka.Hosting spelling: AssertHostingSpellingResolves -- every row, respelled as an AssemblyQualifiedName, still resolves with the switch off.
  • Switch off, default config: AssertBuildsWithoutWarning -- builds without a warning; ids 5 and 36 map to the right classes.
  • Reflection baseline (own to this spec, needs the internal table): with the switch on, the factory-built serializer matches what reflection builds, in class and Identifier, for every bound sample (ClusterHeartbeatSender.Heartbeat, ClusterRouterPool, ConsumerController.Delivery<int>).
  • Override: an application.conf binding (IDeliverySerializable = bytes) takes effect and leaves the other alias alone.

All 5 facts pass on 3 repeated runs.

Mutation checks (done locally, reverted before this PR)

  • Removing ClusterRouterPool from BoundTypes fails the table-matches-config check (and, since it also breaks resolution for every type, several other facts).
  • Adding a bogus bound type (typeof(string)) fails the reverse direction of the table-matches-config check.

Validation

  • dotnet build -c Release -warnaserror: Akka, Akka.Cluster, Akka.Cluster.Tests -- 0 warnings.
  • ClusterSerializersSpec passes on 3 repeated runs.
  • dotnet test src/core/Akka.Tests -c Release -f net10.0 --filter "FullyQualifiedName~Serialization": 128 passed.
  • Akka.API.Tests: 23 passed, no API changes.

Adds ClusterSerializers, covering Cluster.conf's two serializers
(ClusterMessageSerializer, ReliableDeliverySerializer) and their three
bound types, to core's module map. Both classes have a single (system)
constructor and neither has a serialization-settings block in Cluster.conf,
so the factory calls that constructor directly for each.
@Aaronontheweb Aaronontheweb added serialization AOT Ahead-of-Time (AOT) Compilation labels Sep 30, 2026

@Aaronontheweb Aaronontheweb left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

LGTM

@Aaronontheweb
Aaronontheweb merged commit 5644f71 into akkadotnet:dev Sep 30, 2026
16 checks passed
@Aaronontheweb
Aaronontheweb deleted the feature/aot-m2-3a-cluster-serializers branch September 30, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AOT Ahead-of-Time (AOT) Compilation serialization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant